問(wèn)題引入:
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)!專(zhuān)注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、微信小程序開(kāi)發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶(hù)創(chuàng)新互聯(lián)還提供了富平免費(fèi)建站歡迎大家使用!如果有Base類(lèi),B1類(lèi),B2類(lèi),D類(lèi),如下圖繼承關(guān)系
那么按一般的繼承來(lái)看,D類(lèi)創(chuàng)造的對(duì)象會(huì)繼承B1類(lèi)的方法與成員,同時(shí)也會(huì)繼承B2類(lèi)的方法與成員;
接下來(lái)類(lèi)B1 , B2 會(huì)分別去繼承Base類(lèi)的方法與成員,那么D類(lèi)的對(duì)象在調(diào)用Base類(lèi)的方法時(shí),到底是繼承B1類(lèi)這邊的Base,還是會(huì)繼承B2類(lèi)這邊的Base,此時(shí)就會(huì)產(chǎn)生二義性
為了解決這個(gè)問(wèn)題,就看看虛擬繼承是怎么來(lái)解決這個(gè)二義性問(wèn)題的
菱形的虛擬繼承的源代碼
#include <iostream>
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.斷點(diǎn)打到D類(lèi)的構(gòu)造函數(shù)這條語(yǔ)句B1::m_data2 = 0x1;運(yùn)行完D類(lèi)構(gòu)造函數(shù)后調(diào)試。
內(nèi)存1中的地址欄輸入&d可以看到類(lèi)D對(duì)象的模型(取&d因?yàn)樵赥est()函數(shù)創(chuàng)建的是D類(lèi)的d對(duì)象)
3.接下來(lái)問(wèn)題就來(lái)了,明明是取D類(lèi)對(duì)象d的地址,為什么這個(gè)地址下有存儲(chǔ)了地址,里面到底是什么東 西,那就看看吧,(可以看看反匯編和相應(yīng)的內(nèi)存)
此處可以看到它的地址偏移4個(gè)字節(jié)中存儲(chǔ)了0X 00 00 00 14
(這個(gè)數(shù)據(jù)有什么意義哪?)
在看看反匯編就可以了解到編譯器到底在搞什么鬼
看看在給m_data1賦值時(shí),也就是給類(lèi)Base數(shù)據(jù)賦值時(shí),是什么情況
—————————————————————————————————
第一步 取得this指針給寄存器eax
第二步 將寄存器eax中內(nèi)容(即地址 (0x 00 B7 DC C8))給 ecx
第三步 將寄存器exc中內(nèi)容加4 (即 地址(0x 00 B7 DC CC))后,取其地址內(nèi)容給edx(內(nèi)容為 0X 00 00 00 14)
第四步 取this指針給寄存器eax
第五步 eax + edx 的結(jié)果為 (0x 00 30 FD 60 + 0X 00 00 00 14 = 0x 00 30 FD 74),接下來(lái)將數(shù)據(jù)2
存放到這個(gè)地址下
——————————————————————————————————————
從模型圖可以看到地址(0x 00 30 FD 74)就是Base類(lèi)的地址
為什么存放的是數(shù)據(jù)2,但是結(jié)果是4,這就要看清楚了,下面還有條語(yǔ)句未執(zhí)行,
那就是 B2::m_data1 = 0x4;
這就是菱形虛擬繼承下為了不產(chǎn)生二義性的奧妙
(D類(lèi)繼承Base類(lèi)的方法與成員,編譯器在內(nèi)存中只開(kāi)辟了一塊)
創(chuàng)新互聯(lián)www.cdcxhl.cn,專(zhuān)業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。
本文題目:菱形的虛擬繼承-創(chuàng)新互聯(lián)
轉(zhuǎn)載來(lái)源:http://jinyejixie.com/article48/depehp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷(xiāo)、移動(dòng)網(wǎng)站建設(shè)、域名注冊(cè)、網(wǎng)站改版、自適應(yīng)網(wǎng)站、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容