快上网专注成都网站设计 成都网站制作 成都网站建设
成都网站建设公司服务热线:028-86922220

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

菱形的虚拟继承-创新互联

问题引入:

网站建设哪家好,找成都创新互联!专注于网页设计、网站建设、微信开发、微信小程序开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了富平免费建站欢迎大家使用!

 如果有Base类,B1类,B2类,D类,如下图继承关系

 菱形的虚拟继承

那么按一般的继承来看,D类创造的对象会继承B1类的方法与成员,同时也会继承B2类的方法与成员;

接下来类B1 , B2 会分别去继承Base类的方法与成员,那么D类的对象在调用Base类的方法时,到底是继承B1类这边的Base,还是会继承B2类这边的Base,此时就会产生二义性

为了解决这个问题,就看看虚拟继承是怎么来解决这个二义性问题的

  1. 菱形的虚拟继承的源代码

#include

using namespace std;

class Base

{

public:

Base()

{

cout << "Base()  " << this << endl;

}

~Base()

{

cout << "~Base()  " << this << endl;

}

int m_data1;

};

class B1 : virtual public Base

{

public:

B1()

{

cout << "B1()  " << this << endl;

}

~B1()

{

cout << "~B1()  " << this << endl;

}

int m_data2;

};

class B2 : virtual public Base

{

public:

B2()

{

cout << "B2()  " << this << endl;

}

~B2()

{

cout << "~B2()  " << this << endl;

}

int m_data3;

};

class D : public B1, public B2

{

public:

D()

{

B1::m_data2 = 0x1;

B1::m_data1 = 0x2;

B2::m_data3 = 0x3;

B2::m_data1 = 0x4;

m_data4 = 0x5;

cout << "D()" << this << endl;

}

~D()

{

cout << "~D()  " << this << endl;

}

int m_data4;

};

void Test()

{

D d;

//cout << sizeof(D) << endl;   //24

}

int main()

{

Test();

getchar();

return 0;

}

2.断点打到D类的构造函数这条语句B1::m_data2 = 0x1;运行完D类构造函数后调试。

内存1中的地址栏输入&d可以看到类D对象的模型(取&d因为在Test()函数创建的是D类的d对象)

菱形的虚拟继承

3.接下来问题就来了,明明是取D类对象d的地址,为什么这个地址下有存储了地址,里面到底是什么东  西,那就看看吧,(可以看看反汇编和相应的内存)

菱形的虚拟继承

此处可以看到它的地址偏移4个字节中存储了0X 00 00 00 14

(这个数据有什么意义哪?)

在看看反汇编就可以了解到编译器到底在搞什么鬼

菱形的虚拟继承

看看在给m_data1赋值时,也就是给类Base数据赋值时,是什么情况

—————————————————————————————————

第一步 取得this指针给寄存器eax

第二步 将寄存器eax中内容(即地址 (0x 00 B7 DC C8))给 ecx

第三步 将寄存器exc中内容加4 (即 地址(0x 00 B7 DC CC))后,取其地址内容给edx(内容为 0X 00 00 00 14)

第四步 取this指针给寄存器eax

第五步 eax + edx 的结果为 (0x 00 30 FD 60 +  0X 00 00 00 14 = 0x 00 30 FD 74),接下来将数据2

   存放到这个地址下

——————————————————————————————————————

从模型图可以看到地址(0x 00 30 FD 74)就是Base类的地址

为什么存放的是数据2,但是结果是4,这就要看清楚了,下面还有条语句未执行,

那就是  B2::m_data1 = 0x4;

这就是菱形虚拟继承下为了不产生二义性的奥妙

(D类继承Base类的方法与成员,编译器在内存中只开辟了一块)

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


名称栏目:菱形的虚拟继承-创新互联
网站地址:http://6mz.cn/article/depehp.html

其他资讯