📅  最后修改于: 2023-12-03 14:51:15.308000             🧑  作者: Mango
在C++中,虚函数是一个在基类中声明、且被派生类重新定义的成员函数。非虚函数是一个在基类中声明、但未被派生类重新定义的成员函数。当在非虚函数内部调用虚函数时,会发生以下情况:
如果从基类中调用虚函数,那么将会调用基类中的实现,而不是派生类中的实现。这是因为虚函数解析是在运行时进行的,而在编译时就已经确定了非虚函数的实现。例如:
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
中的实现。
如果从派生类中调用虚函数,那么将会调用派生类中的实现。但是如果派生类中没有重新定义虚函数,那么将会调用基类中的实现。例如:
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()
。
综上所述,在非虚函数内部调用虚函数时,实际调用的函数取决于该函数被定义的类的类型。如果定义了该函数的类是基类,则调用基类的实现;如果定义了该函数的类是派生类,则调用派生类的实现(如果有)或者基类的实现(如果派生类没有重新定义该虚函数)。