C++ 继承和虚函数

C++ inheritance and virtual functions

阅读一本教科书后,我的印象是重写虚函数仅在使用指针或对象引用时有效。这本书演示了创建指向派生 class 类型的对象的基本 class 类型的指针,并使用它来演示虚函数覆盖。

但是,我现在遇到了以下情况。看不到指针,我原以为将 function1 设为虚拟不会有什么不同,但确实如此。我显然在这里遗漏了一些东西,希望能解释一下它是什么。对不起,如果我的解释不清楚;我也希望之前有人问过这个问题,但无法想出要搜索的内容。

using namespace std;

class ClassA
{
public:
    void function1(); // virtual or not?
    void function2();
};

class ClassB : public ClassA
{
public:
    void function1();
};

int main()
{
    ClassA objA;
    ClassB objB;

    objA.function1();
    cout << "\n";
    objA.function2();
    cout << "\n";
    objB.function1();
    cout << "\n";
    objB.function2(); // Fourth call
    cout << "\n";
}

void ClassA::function1() { cout << "ClassA::function1\n"; }

void ClassA::function2()
{
    cout << "ClassA::function2\n";
    function1(); // For the fourth call ClassA::function1()
                    // is called if ClassA::function1() is not virtual
                    // but ClassB:function1() is called if it is.  Why? 
}

void ClassB::function1() { cout << "ClassB::function1\n"; }

非常感谢您的帮助。

它不是虚函数,因为它没有被标记为虚函数。它只是来自派生的 class / 对象的 public 函数 accessible。您的代码也没有表现出多态行为。也就是说 none 你的函数是 virtual nor overriding。多态安装的简单示例是:

#include <iostream>
#include <memory>

class ClassA {
public:
    virtual void function1() { // now virtual
        std::cout << "ClassA::function1\n";
    }
};

class ClassB : public ClassA {
public:
    void function1() override {
        std::cout << "ClassB::function1\n";
    }
};

int main() {
    std::unique_ptr<ClassA> p = std::make_unique<ClassB>();
    p->function1(); // now calls class B function, overrides class A behavior
}

或通过参考:

int main() {
    ClassB objB;
    ClassA& ro = objB;
    ro.function1(); // now calls class B function, overrides class A behavior
}

如果您不使用多态行为,将函数标记为 virtualoverride 没有什么好处。

function1 不是虚拟的,obj2 调用 classB function1 因为它是一个 clasB 对象,编译器首先查看函数的最派生类型,然后是最左边的基(并通过该基的基) ,然后是多重继承情况下的下一个基数。如果您将 classA * 带到 obj2 并调用 function1,它将调用 classA function1。

没有显式指针的虚拟示例:

class A
{
    public:
        virtual void f1()
        {
            cout << "A::f1()" << endl;
        }

        void f2()
        {
            f1();
        }
};

class B : public A
{
    public:
        void f1() override
        {
            cout << "B::f1()" << endl;
        }
};

int main()
{
    A a;
    B b;
    a.f2();
    b.f2();
}