转自 https://www.cnblogs.com/fanzhidongyzby/archive/2013/01/14/2859064.html
主要讲解了单继承、多继承、虚继承的对象模型,尤其是虚函数在继承中的内部实现等!
class MyClass
{
int var;
public:
virtual void fun()
{}
};
class MyClassA:public MyClass
{
int varA;
public:
virtual void fun()
{}
virtual void funA()
{}
};
class MyClassB:public MyClass
{
int varB;
public:
virtual void fun()
{}
virtual void funB()
{}
};
class MyClassC:public MyClassA,public MyClassB
{
int varC;
public:
virtual void funB()
{}
virtual void funC()
{}
};
要点:
①虚函数调用形式,应该是:*(this指针+调整量)虚函数在vftable内的偏移
②在单继承形式下,子类的完全获得父类的虚函数表和数据。子类如果重写了父类的虚函数(如fun),就会把虚函数表原本fun对应的记录(内容MyClass::fun)覆盖为新的函数地址(内容MyClassA::fun),否则继续保持原本的函数地址记录。如果子类定义了新的虚函数,虚函数表内会追加一条记录,记录该函数的地址(如MyClassA::funA)。
③如果使用MyClassA对象直接访问fun,则不会出发多态机制,因为这个函数调用在编译时期是可以确定的,编译器只需要直接调用MyClassA::fun即可。
④多重继承下,子类不再具有自身的虚函数表,它的虚函数表与第一个父类的虚函数表合并了。同样的,如果子类重写了任意父类的虚函数,都会覆盖对应的函数地址记录。如果MyClassC重写了fun函数(两个父类都有该函数),那么两个虚函数表的记录都需要被覆盖!
class MyClassA:virtual public MyClass
class MyClassB:virtual public MyClass
class MyClassC:public MyClassA,public MyClassB