请告诉我为什么虚函数在以下代码中不起作用

Ars*_*shi 2 c++ oop polymorphism virtual-functions

当我运行此代码时,由于后期绑定,输出如预期的“这是派生 2”,因为我们在基类中使用了虚函数。

    #include <iostream>
    using namespace std;

    class  Base {
        public :
        virtual void show() {
            cout<<"This is base class"<<endl;
        }
    };
    class  Derived : public Base {
        public:
        void show() {
            cout<<"This is derived class"<<endl;
        }
    };

    class D2 : public Derived {
        public :
        void show () {
            cout<<"This is derived 2"<<endl;
        }
    };

    int main() {
        Base *obj = new D2();
        obj->show();
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

同样,如果我将代码更改为

        #include <iostream>
        using namespace std;

        class  Base {
            public :
             void show() {
                cout<<"This is base class"<<endl;
            }
        };
        class  Derived : public Base {
            public:
            virtual void show() {
                cout<<"This is derived class"<<endl;
            }
        };

        class D2 : public Derived {
            public :
            void show () {
                cout<<"This is derived 2"<<endl;
            }
        };

        int main() {
            // your code goes here
            Derived *obj = new D2();
            obj->show();
            return 0;
        }
Run Code Online (Sandbox Code Playgroud)

同样的事情发生了,虚函数是在基类中定义的,在本例中是“派生”类,并且指针也是“派生”类型,因此再次调用 show() 会给出最派生的版本。

但我无法理解当在“派生”类中定义虚函数并且我使用“基”类的基指针时会发生什么。以下代码的输出

    #include <iostream>
    using namespace std;

    class  Base {
        public :
         void show() {
            cout<<"This is base class"<<endl;
        }
    };
    class  Derived : public Base {
        public:
        virtual void show() {
            cout<<"This is derived class"<<endl;
        }
    };

    class D2 : public Derived {
        public :
        void show () {
            cout<<"This is derived 2"<<endl;
        }
    };

    int main() {
        // your code goes here
        Base *obj = new D2();
        obj->show();
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

输出:“这是基类”。请帮助我理解这个输出。

das*_*ght 5

最后一个代码片段不起作用的原因是该void show()函数virtual仅在派生类中,而不在基类中。如果从 派生的任何类Derived将重写它,然后通过指向 的指针调用它Derived,您将看到多态行为。然而,按照您的方式,通过基指针的调用是非虚拟的,因此它被分派到 的Base实现。

您可以通过show在基类中声明 virtual 来解决此问题:

class  Base {
    public :
    virtual void show() {
//  ^^^^^^^
        cout<<"This is base class"<<endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

演示1

或者D2通过指针访问Derived

Derived *obj = new D2();
obj->show();
Run Code Online (Sandbox Code Playgroud)

演示2