有这样三个类的声明:
class A {
public:
virtual void fun1() {
cout << "A::fun1" << endl;
}
};
class B : public A {
public:
virtual void fun1() {
cout << "B::fun1" << endl;
}
virtual void fun2() {
cout << "B::fun2" << endl;
}
};
class C : public B {
public:
virtual void fun2() {
cout << "C::fun2" << endl;
}
};
B *pb1 = new B;
B *pb2 = new C;
pb1->fun2(); // B::fun2
pb2->fun2(); // C::fun2
B继承A后,新声明了个虚函数fun2,并被C继承,此时用B的指针指向C的对象可以实现多态。然而观察内存发现B和C的虚函数表里只保存了fun1的地址,并没有fun2的地址:
即使直接观察内存也是没有的:
可以看到C的虚函数表里,第一个地址0x008814e7就是B::fun1的地址,而后一个地址0x008814dd却不是B::fun2或C::fun2的地址
那么,程序在运行时是怎么找到fun2的地址的呢?
真实的情况是这样的。你的B不仅覆盖了A,还增加了一个虚函数,所以B里面就会有两张虚函数表,一张用来保存fun1,一张用来保存fun2。
因此写成C语言大概就这样: