最近,從師兄那裡聽到一道據說是某國內知名
it公司的面試題,有關
c++虛擬繼承的。
#include
using
namespace std;
class t ;
class a : virtual
public t ;
class b : virtual
public t ;
class c : public a, public b ;
class d : public a, virtual
public b ;
class e : virtual
public a, virtual
public b ;
int main()
//問輸出結果?
/*vc6.014
48812
devc++5.0, 32位,核心是gcc14
4888
g++ 4.1, 64位18
8161616
*//*
c++物件模型裡面有提到的另一種情況(即沒對empty virtual base class做優化),不知道是用那種c++編譯器,其結果如下:
sizeof(t) = 1
sizeof(a) = 8
sizeof(b) = 8
sizeof(c) = 12*/
之前只是了解虛擬繼承是為
c++多繼承時,同一基類在派生層次中多次出現,引起的儲存空間浪費,和二義性,而提出來的解決方案。而對具體的物件資料布局,就不是很清楚了,在
vc++6.0
上跑了一下這個程式,照著結果理解了半天都沒找到能夠同時把
c(8),d(8),e(12)
三個都解釋得通的模型。
在**找來一些資料,也是眾說紛紜。最後下了
jjhou
譯的《深入探索
c++物件模型》看了第3章
data
語義學部分,講得較為詳細。對其中主要部分解釋總結如下:
1.語言本身造成的額外負擔,即虛擬繼承中子類中必須儲存指向
virtual base class subobject
的指標或乙個相關**的偏移量。指標的大小跟機器有關;
2.編譯器對於特殊情況所提供的最佳化處理,
virtual base class subobject
會放在derived class
的固定(不變動)部分尾端,即上述t的
1byte
大小會出現在
a,b上。而有些編譯器會對虛擬繼承中的空基類提供優化處理,在這種策略下,乙個
empty virtual base class
就被視為
derived class object
最開頭的一部分,而它並沒有花費任何額外的空間,如vc++6.0裡sizeof(a)=4;
3.alignment
的限制,如果不考慮對
empty virtual base class
進行優化,a和
b大小截止到目前為
5bytes
。在大部分機器上,結構體大小受
alignment
限制,以使它們能夠更有效率地在記憶體中被訪問,上面測試的結構所使用的機器均為
4bytes
對齊,即會出現上述最後一種情況sizeof(a)=8。關於
alignment自己想了
乙個的例子如下:
class s ;//sizeof(s)=12
嘿,總之c++
的物件布局,除了語言本身外,還要考慮機器,編譯器的因素。這些拿來當筆試面試的題目,還真不好答。 至於
sizeof(e)
的大小vc6.0
與devc++5.0
的不同還是不清楚
…暈,應該也是編譯器處理策略不同引起的。
sizeof(t)為1
:根據物件唯一性原則,編譯器隱晦插入乙個位元組,以使類的不同例項,在記憶體中擁有唯一的位址。
C 物件模型(中)多繼承
例如下面 class b virtual void func 2 虛函式 protected int b class c virtual void func 3 虛函式 protected int c class d public b public c virtual void func 4 der...
繼承中的物件模型
1 在子類物件構造時,需要呼叫父類建構函式對其繼承得來的成員進行初始化 2 在子類物件析構時,需要呼叫父類析構函式對其繼承得來的成員進行清理 繼承中的構造析構呼叫原則 建構函式執行順序 1 先執行父類的建構函式 2 再執行子類的建構函式 析構函式執行順序 1 先執行子類析構函式 2 再執行父類析構函...
繼承中的物件模型
繼承中的物件模型 問題 從父類繼承過來的成員,哪些屬於子類物件中?示例 include using namespace std 繼承中的物件模型 class base class son public base 利用開發人員命令提示工具檢視物件模型 跳轉碟符 f 跳轉檔案路徑 cd 具體路徑下 檢視...