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)如果派生类新增虚函数,则新增添到虚表后面