📜  在C++中的非虚函数内部调用虚函数时会发生什么(1)

📅  最后修改于: 2023-12-03 14:51:15.308000             🧑  作者: Mango

在C++中的非虚函数内部调用虚函数时会发生什么

在C++中,虚函数是一个在基类中声明、且被派生类重新定义的成员函数。非虚函数是一个在基类中声明、但未被派生类重新定义的成员函数。当在非虚函数内部调用虚函数时,会发生以下情况:

  1. 调用基类的虚函数

如果从基类中调用虚函数,那么将会调用基类中的实现,而不是派生类中的实现。这是因为虚函数解析是在运行时进行的,而在编译时就已经确定了非虚函数的实现。例如:

class Base {
public:
    virtual void foo() {
        std::cout << "Base::foo()\n";
    }
    void bar() {
        std::cout << "Base::bar()\n";
        foo();
    }
};

class Derived : public Base {
public:
    void foo() override {
        std::cout << "Derived::foo()\n";
    }
};

int main() {
    Derived d;
    d.bar();
    return 0;
}

输出:

Base::bar()
Base::foo()

Base::bar()函数内部调用了虚函数foo(),但是输出了基类Base的实现,而不是派生类Derived中的实现。

  1. 调用派生类的虚函数

如果从派生类中调用虚函数,那么将会调用派生类中的实现。但是如果派生类中没有重新定义虚函数,那么将会调用基类中的实现。例如:

class Base {
public:
    virtual void foo() {
        std::cout << "Base::foo()\n";
    }
};

class Derived : public Base {
public:
    void bar() {
        std::cout << "Derived::bar()\n";
        foo();
    }
};

int main() {
    Derived d;
    d.bar();
    return 0;
}

输出:

Derived::bar()
Base::foo()

Derived::bar()函数内部调用了虚函数foo(),但是输出了基类Base的实现,因为派生类Derived没有重新定义虚函数foo()

综上所述,在非虚函数内部调用虚函数时,实际调用的函数取决于该函数被定义的类的类型。如果定义了该函数的类是基类,则调用基类的实现;如果定义了该函数的类是派生类,则调用派生类的实现(如果有)或者基类的实现(如果派生类没有重新定义该虚函数)。