有这样三个类的声明:
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語言大概就這樣: