C 虛擬繼承中的物件模型

2021-04-21 09:22:12 字數 2001 閱讀 2362

最近,從師兄那裡聽到一道據說是某國內知名

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 具體路徑下 檢視...