有人可以帮我理解虚拟函数在这里是如何工作的,即使调用不是通过指针或引用的?
#include <iostream>
class Base {
public:
virtual void f() { std::cout << "Base::f()" << std::endl; }
void g() { f(); }
};
class Derived : private Base {
public:
void f() { std::cout << "Derived::f()" << std::endl; }
void h() { g(); }
};
int main(){
Derived d;
d.h(); // prints Derived::f() but if virtual keyword is removed from Base::f() then prints Base::f()
}
对d.h()
的调用不是通过指针或引用进行的,是的。
但是对f()
的调用是通过指针进行的 - 一个隐式的this
指针。
Base::f()
被Derived::f()
virtual
和覆盖,所以任何通过Base*
指针(或Base&
引用)对f()
的调用,在引用Derived
对象的Base
部分时,都会多态地调度给Derived::f()
。
Derived::h()
在调用g()
,这真的很this->g()
,其中this
是一个Derived*
指针。g()
继承自Base
,并且可以在Derived
对象上调用。g()
不是virtual
,所以Base::g()
被静态调用,其this
指向Derived
对象的Base
部分。Base::g()
调用f()
,这真的很this->f()
,其中this
是一个Base*
指针。f()
是virtual
的,因此执行多态调度,并且由于this
指向(Derived
对象的Base
部分),因此Derived::f()
被调用而不是Base::f()
。
如果从Base::f()
中删除virtual
,则在Base*
指针(或Base&
引用)上调用f()
将无条件静态调用Base::f()
,不执行多态调度。
有人可以帮我理解虚函数在这里是如何工作的,即使调用不是通过指针或引用的?
它不需要,以获得运行时多态性。
这是一个神话,可能是通过学校和互联网上过于简化的说法传播的。
运行时多态性总是"工作",如果你的类是这样设计的(即带有virtual
)。
如果存储基类型的对象,则会切掉派生部分,因此无法获得所需的结果。存储指针是解决此问题的常见方法,但这并不意味着指针支持运行时多态性。