C++物件版面配置及多態實現探索之虛繼承

來源:互聯網
上載者:User

下面我們來看虛繼承。首先看看這C020類,它從C010虛繼承:}

struct C010
{
 C010() : c_(0x01) {}
 void foo() { c_ = 0x02; }
 char c_;
};
struct C020 : public virtual C010
{
 C020() : c_(0x02) {}
 char c_;
};

運行如下代碼,查看對象的記憶體布局:

PRINT_SIZE_DETAIL(C020)

結果為:

The size of C020 is 6
The detail of C020 is c0 c2 45 00 02 01

很明顯對象的起始處是一個指標,然後是子類的成員變數,接下來是父類的成員變數。和以前的討論不同的是由於使用了虛繼承,父類的成員變數被放到了最後面。

運行如下的代碼:

C020 c020;
c020.C010::c_ = 0x04;

由於子類中的變數和父類中的變數重名,所以我們必須用這種方式來訪問屬於父類的成員變數,普通情況下不需要這種寫法。我們看看後面這行代碼對應的彙編代碼:

0042387E mov eax,dword ptr [ebp+FFFFF82Ch]
00423884 mov ecx,dword ptr [eax+4]
00423887 mov byte ptr [ebp+ecx+FFFFF82Ch],4

前面說過對象的起始是一個指標,第1行指令取到這個指標的值,第2行把這個指標指向的地址後移4位元組後的值(做為一個4位元組的值)取出來。執行完這句我們看看ecx寄存器,可知取出來的值為5。最後一行是真正的賦值指令,它通過在對象的起始處(即[ebp+FFFFF32Ch])加上ecx中的值做位移值(即5)來得到賦值的目的地址。接合前面的物件版面配置輸出,我們可以發現從對象起始地址開始加5位元組的位移值,剛好得到父類的成員變數的地址。這樣我們可以大致分析出直接虛繼承的子類的物件版面配置。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.