91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

菱形的虛擬繼承

發布時間:2020-06-27 15:37:57 來源:網絡 閱讀:429 作者:q874770616 欄目:編程語言


問題引入:

   如果有Base類,B1類,B2類,D類,如下圖繼承關系

   菱形的虛擬繼承


那么按一般的繼承來看,D類創造的對象會繼承B1類的方法與成員,同時也會繼承B2類的方法與成員;

接下來類B1 , B2 會分別去繼承Base類的方法與成員,那么D類的對象在調用Base類的方法時,到底是繼承B1類這邊的Base,還是會繼承B2類這邊的Base,此時就會產生二義性

 

為了解決這個問題,就看看虛擬繼承是怎么來解決這個二義性問題的


  1.  菱形的虛擬繼承的源代碼


#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.斷點打到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類的方法與成員,編譯器在內存中只開辟了一塊)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

江永县| 康平县| 昭通市| 九江市| 贡嘎县| 哈密市| 康定县| 丽水市| 明星| 芜湖县| 中西区| 宜黄县| 石柱| 南昌县| 白河县| 密山市| 大埔县| 水城县| 博客| 阿勒泰市| 长治市| 宁陵县| 洛阳市| 远安县| 荥阳市| 海林市| 吐鲁番市| 亚东县| 汶川县| 长葛市| 安福县| 辛集市| 来宾市| 会昌县| 中宁县| 桂东县| 三都| 旌德县| 平果县| 邢台市| 南昌县|