C++多重繼承下的指標類型轉換

來源:互聯網
上載者:User

在C++中,指標的類型轉換是經常發生的事情,比如將衍生類別指標轉換為基類指標,將基類指標轉換為衍生類別指標。指標的本質其實就是一個整數,用以記錄進程虛擬記憶體空間中的地址編號,而指標的類型決定了編譯器對其指向的記憶體空間的解釋方式。

基於上面的理解,我們似乎可以得出一個結論,C++中對指標進行類型轉換,不會改變指標的值,只會改變指標的類型(即改變編譯器對該指標指向記憶體的解釋方式),但是這個結論在C++多重繼承下是 不成立的。

看下面一段代碼:

 1 #include <iostream> 2 using namespace std; 3  4 class CBaseA 5 { 6 public: 7     char m_A[32]; 8 }; 9 10 class CBaseB11 {12 public:13     char m_B[64];14 };15 16 class CDerive : public CBaseA, public CBaseB17 {18 public:19     char m_D[128];20 };21 22 23 int main()24 {25     auto pD = new CDerive;26     auto pA = (CBaseA *)pD;27     auto pB = (CBaseB *)pD;28 29     cout << pA << '\n' << pB << '\n' << pD << endl;30     cout << (pD == pB) << endl;31 }

這段代碼的輸出是:

0x9f1080
0x9f10a0
0x9f1080
1

可以看出,指向同一個堆上new出來的記憶體指標,在經過類型轉換之後,其值會發生改變。究其原因,要從C++中多重繼承的記憶體布局說起。

new CDerive;執行之後,產生的記憶體布局如下:

 

同時我們注意到,pB與pD的指標差值正好是CBaseA佔用的記憶體大小32位元組,而pA與pD都指向了同一段地址。這是因為,將一個衍生類別的指標轉換成某一個基類指標,編譯器會將指標的值位移到該基類在對象記憶體中的起始位置。

可是為什麼C++要這樣設計呢?

試想,沿用上面的情境,如果pB和pA都指向對象的首地址,那麼使用pB指標來定位CBaseB的成員變數m_B時,編譯器應該將pB指標位移32個位元組,從而跳過CBaseA的記憶體部分。而pB指標如果是這樣產生的auto pB = new CBaseB;,那麼使用pB指標來定位CBaseB的成員變數m_B時,位移量應該為0。

關鍵在於對於一個指標而言,編譯器不關心也無法知道該指標的來源(一種極端情況,指標是從其他模組傳遞過來的),而只是把它視為一個有指標類型的整數。所以對於CBaseB類型的指標,取CBaseB的成員變數m_B時,位移量應該通通為0,這是通過CBaseB的類聲明就可以統一決策的事情。

說到這裡,pD和pB的指標地址為什麼不一樣大家應該清楚了,可是為什麼下面的代碼輸出是1呢?

cout << (pD == pB) << endl;

輸出1表示pD和pB是相等的,而剛剛我們才說明了,pD和pB的地址是相差了32個位元組的。

其實這也是編譯器為大家屏蔽了這種指標的差異,當編譯器發現一個指向衍生類別的指標和指向其某個基類的指標進行==運算時,會自動將指標做隱式型別提升已屏蔽多重繼承帶來的指標差異。因為兩個指標做比較,目的通常是判斷兩個指標是否指向了同一個記憶體對象執行個體,在上面的情境中,pD和pB雖然指標值不等,但是他們確確實實都指向了同一個記憶體對象(即new CDerive;產生的記憶體對象 ),所以編譯器又在此處插了一腳,讓我們可以安享==運算的上層語義。

 

 

from:http://www.cnblogs.com/itZhy/archive/2012/10/08/2713367.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.