3.多繼承模型
看下面代碼:
class Base1
{
public:
Base1():_b1(1)
{}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
private:
int _b1;
};
class Base2
{
public:
Base2():_b2(2)
{}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
private:
int _b2;
};
class Derive:public Base1,public Base2
{
public:
Derive():_d(3)
{}
virtual void fun2()
{
cout<<"Derive::fun2()"<<endl;
}
virtual void fun4()
{
cout<<"Derive::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Derive::fun5()"<<endl;
}
private:
int _d;
};
int main()
{
Base1 b1;
Base2 b2;
Derive d;
cout<<sizeof(d)<<endl;//20
return 0;
}
這裏d的大小爲什麼是20呢,下面給出d的對象模型:
看下內存:
用下面函數打印之:(注:VS2008環境)
void test()
{
Derive d;
pfun* p = (pfun*)*((int*)(&d));
PrintVirtual(p);
p-=4;
PrintVirtual(p);
}
多重繼承編譯器是怎麼做的呢?
1)先將基類的虛表中的內容各自拷貝一份,有幾個基類,就有幾個虛表
2)如果派生類對基類中的虛函數進行重寫,就是用派生類中的虛函數替換相同偏移位置的基類虛函數
3)派生類將自己新增的虛函數放在第一個基類虛表後面
4.含虛繼承的多繼承(菱形繼承)
class Base
{
public:
Base():_b(1)
{}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
private:
int _b;
};
class C1:public virtual Base
{
public:
C1():_c1(2)
{}
virtual void fun2()
{
cout<<"C1::fun2()"<<endl;
}
virtual void fun3()
{
cout<<"C1::fun3()"<<endl;
}
private:
int _c1;
};
class C2:public virtual Base
{
public:
C2():_c2(3)
{}
virtual void fun4()
{
cout<<"C1::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"C1::fun5()"<<endl;
}
private:
int _c2;
};
class Derive:public C1,public C2
{
public:
Derive():_d(4)
{}
virtual void fun3()
{
cout<<"Derive::fun3()"<<endl;
}
virtual void fun5()
{
cout<<"Derive::fun5()"<<endl;
}
virtual void fun6()
{
cout<<"Derive::fun6()"<<endl;
}
private:
int _d;
};
int main()
{
cout<<sizeof(Derive)<<endl;//36
return 0;
}
下面給出Derive的對象模型:
用下面函數打印驗證之:
void test()
{
Derive d;
pfun* p = (pfun*)*((int*)(&d));
PrintVirtual(p);
p-=4;
PrintVirtual(p);
p-=3;
PrintVirtual(p);
}
C1,C2的虛表生成機制和前面類似多繼承一樣。
菱形虛擬繼承派生類虛表:
1)覆蓋基類的的虛函數
2)如果派生類新增虛函數,則新增添到虛表後面