对于这样一个类:
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
实例化:
则Base b的虚函数表为:
下面分类讨论:
1、一般继承(无虚函数覆盖)
则Derive &b的虚函数表:
可见:
- 虚函数按照其声明顺序放于表中。
- 父类的虚函数在子类的虚函数前面。
2、一般继承(有虚函数覆盖)
则Derive &b的虚函数表:
可见:
- 覆盖的f()函数被放到了虚表中原来父类虚函数的位置。
- 没有被覆盖的函数依旧。
3、多重继承(无虚函数覆盖)
则Derive d的虚函数表:
可见:
- 每个父类都有自己的虚表。
- 子类的成员函数被放到了第一个父类的表中。(所谓的第一个父类是按照声明顺序来判断的)
这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。
4、多重继承(有虚函数覆盖)
则Derive d的虚函数表:
可见:
- 三个父类虚函数表中的f()的位置被替换成了子类的函数指针。
这样,我们就可以任一静态类型的父类来指向子类,并调用子类的f()了