重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
class B
站在用户的角度思考问题,与客户深入沟通,找到高平网站设计与高平网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都网站制作、网站建设、外贸网站建设、企业官网、英文网站、手机端网站、网站推广、国际域名空间、网络空间、企业邮箱。业务覆盖高平地区。{
public:
int b;
};
class C1 :virtual public B
{
public:
int c1;
};
class C2 :virtual public B
{
public:
int c2;
};
class D :public C1, public C2
{
public:
int d;
};
int main()
{
cout << sizeof(D ) << endl; //24
B b;
D d;
system( "pause");
return 0;
}
在类D中添加函数,改为:
class D :public C1, public C2
{
public:
void Display()
{
c1 = 0x02;
C2::b = 0x03;
c2 = 0x04;
d = 0x05;
cout << "this=" << this << endl << endl;
cout << "&C1::b=" << &(C1 ::b) << endl;
cout << "&c1=" << &c1 << endl;
cout << "&C2::b=" << &(C2 ::b) << endl;
cout << "&c2=" << &c2 << endl;
cout << "&d=" << &d << endl;
cout << b << endl;
}
int d;
};
主函数写为:
int main()
{
cout << sizeof(D ) << endl; //24
B b;
D d;
d.Display();
C1 c;
system( "pause");
return 0;
}
调试截图为:
原理分析:
因为类B是类C1和类C2的基类,所以C1和C2都会继承B的数据成员b,所以C1和C2中会存在同名成员,当类D继承类C1和类C2的时候,就会有两个数据成员b,这样会保留多份数据成员的拷贝,不仅占用较多的存储空间,还增加了访问这些成员的困难,实际上,我们也不需要有多份拷贝。
为了解决这一问题,我们让类C1和类C2在继承B的时候进行了虚继承,即在继承方式前加virtual ,虚基类使得在继承间接共同基类时只保留一份成员。
数据结果分析:
在代码中,我们只给类C1中继承的b赋值为3,但是截图显示,类C1和类C2中的数据成员b的值都为3,而且类C1和类C2 中数据成员Bde地址是一样的,这就验证了“虚基类使得在继承间接共同基类时只保留一份成员 ”
虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的。
声明虚基类的一般方式为:
class 派生类名:virtual 继承方式 基类名
在最后的派生类中,不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化
对于这个例子
有虚基类的时候:
没有虚基类的时候:
没有虚基类的时候,对于这种菱形继承,派生类D中会有两个数据成员int b,也是因此,在访问的时候必须要写清楚访问的是那个类里面的b成员,如C1::b,否则会因为访问成员不明确而造成错误,为了避免这一问题,要在声明继承方式的时候加上virtual关键字,表示这是一个虚继承
通过看内存,可以清楚的看到在类D中,最后继承下来的数据成员是如何放置的
c1中的虚基类地址存储的偏移量20
c2中的虚基类地址存储的偏移量12
在内存中大概就是这个样子:
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。