1.单继承
class Base
{
public:
int _b;
};
class Derived:public Base
{
public:
int _d;
};
int main()
{
Derived d;
d._b=10;
d._d =20;
}
单继承对象模型如下:
2.多继承
class B1
{
public:
int _b1;
};
class B2
{
public:
int _b2;
};
class Derived:public B1,public B2
{
public:
int _d;
};
int main()
{
Derived d;
d._b1=10;
d._b2 =30;
d._d =20;
}
多继承对象模型如下:
3.菱形继承
class Base
{
public:
int _b;
};
class C1 :public Base
{
public:
int _c1;
};
class C2:public Base
{
public:
int _c2;
};
class Derived:public C1,public C2
{
public:
int _d;
};
int main()
{
cout<<sizeof(d)<<endl;
Derived d;
//d._b =10;//会报错
d.Base::_b =10;
d._c1 =20;
d._c2 =30;
d._d =40;
}
但是,这里又有一个问题,那就是在最底下的派生类中,会有两份_b,在对象d1中访问_b就会出错,如果想要访问,俊必须加访问限定符,如何解决这个问题,就引出了虚拟继承
4.虚拟继承
虚拟继承就是在继承权限的前面加上virtual关键字
class Base
{
public:
int _b;
};
class Derived: virtual public Base
{
public:
int _d;
};
int main()
{
Derived d;
cout<<sizeof(d)<<endl;
d._b =1;
d._d =2;
return 0;
}
为什么增加了四个字节呢,这是因为编译器会合成构造函数(给前4个字节放偏移量表格的地址)
对象模型如下
5.菱形虚拟继承
class Base
{
public:
int _b;
};
class C1 :virtual public Base
{
public:
int _c1;
};
class C2:virtual public Base
{
public:
int _c2;
};
class Derived:public C1,public C2
{
public:
int _d;
};
int main()
{
Derived d;
cout<<sizeof(d)<<endl;
d._b =10;
d._c1 =20;
d._c2 =30;
d._d =40;
}
由打印结果可知,大小为24,有内存窗口可知,基类的成员_b确实只存放了一份,这24个字节,除_b,_c1,_c2,_d外还有8字节,这8字节存放都是地址,指向也都是一张存放偏移量表格。
虚拟菱形继承对象模型如下: