2014-03-06 96 views
2

可以安全地假設在一個非虛擬單繼承類層次結構中(包含或不包含模板)子類和父類的基類指針是相同的?而根類的第一個成員也總是在同一位置(首先暗示第二,但這是我主要關注的)非虛擬單繼承類層次結構中的基指針一致性

struct parent { 
    int type_ = 0; 
    parent(int type):type_(type) {} 
}; 

struct child: parent { 
    child():parent(1) {} 
}; 

child ch; 
printf("parent %p\r\n", &static_cast<parent&>(ch).type_); 
printf("child %p\r\n", &static_cast<child&>(ch).type_); // :) 

從我的C++ - 福,常識和測試中,它應該是,但我正在尋找一個C++標準兼容的答案來安慰我。 :)

PS請參閱ideone.com上的代碼。

+1

在'child'的一個實例裏只有'type_'的一個副本,所以當然你可以保證得到相同的地址。我懶得追捕章節和詩歌,但它看起來像這樣。在第一種情況下,'static_cast'給你一個'child'內的明確基類的實例,然後你訪問它的成員。在第二種情況下,'static_cast'是一個no-op;但名稱查找在同一個明確的基類中找到'type_'。 –

回答

3

這兩個類都是「標準佈局類」的示例。標準規定,此類必須與C樣式的存儲器佈局兼容。這意味着,指向類對象的指針始終與指向該類的第一個數據成員的指針相同。所以,是的,它是由標準強制的。 (我現在試圖找到對「標準佈局類」)的引用。

編輯:(從this question採取的定義,我沒有標準的手,抱歉)

標準佈局類是一類:

  • 沒有非靜態沒有虛擬函數(10.3) 並且沒有虛擬基類(10.1),
  • 具有相同的訪問控制(第11章)或類似非標準佈局類的數據成員(或 此類數組)爲所有非靜態數據 成員,
  • 沒有非標準佈局基類,
  • 或者具有沒有非靜態數據成員在最派生類,並在與非靜態數據成員最多有一個基類,或沒有帶有非靜態數據成員的基類,並且
  • 沒有與第一個非靜態數據 成員相同類型的基類。
+2

請參閱[class]/7和[class.mem]/19 – dyp

+0

**謝謝!**我知道必須有一個正式的名稱。 – CodeAngry

+0

請注意標準佈局類是C++ 11的一個特性。C++ 98/2003只知道POD和非POD類。 – Jens

0

您總是可以將派生類轉換爲基類。

class Base{ 
public: 
    int n; 
}; 

class Derived: public base{ 

}; 


//you can do this: 
Derived obj; 
Base *p = &obj;//just take the derived address and put in base pointer, without cast. 
cout<<p->n; 

這意味着基地的成員總是位於派生的開始和相同的順序。