3

C++:我如何知道基類SubObject的大小?

Here我正在討論空基類優化和MSalters使這個有趣的評論:

無級永遠不會有 的sizeof(類)== 0,空。 但是 我們正在專門討論空基類子對象的 大小。 它不需要它自己的虛表,也不需要一個 虛表指針。假設在偏移量爲 0處的vtable指針的佈局是共同的 ;這會導致零大小的 基類子對象與派生類共享其 vtable指針。 沒問題:無論如何這些應該是相同的 ,這幾乎是虛擬功能的點 。

我的問題具體是這樣的:編譯器可以優化當我們使用空類作爲基類,或者它可能不會。我們如何確定它實際上做了什麼?

一般來說,我們如何知道基類子對象的大小?無論我們是否將它用作基礎,Base Base子對象的大小是否相同?編譯器是否僅使用空基類進行優化?

回答

4

很好的答案。

順便說一句,MS VC++和G ++編譯器可以轉儲類的佈局,供您學習。

用VC++只運行cl.exe /c /d1reportAllClassLayout <source>.cpp

它使用類和虛函數表佈局轉儲代碼,我在1990年寫的,測試正確的佈局對象,虛函數表,vbtables等

爲了更好地瞭解C++編譯器如何對對象進行佈局在內存中,您可能會喜歡http://www.openrce.org/articles/files/jangrayhood.pdf和Stan Lippman的書Inside the C++ Object Model。

快樂黑客!

0

你不能。作爲基地時,實際尺寸可能與sizeof()信息有很大差異。

除EBO之外的另一個例子是虛擬繼承。

2

對象的鉛丹尺寸爲1:

class X {}; 
sizeof(X) >= 1 

但派生類並不需要分配空間,這個空間如果不使用它:

class Y : public X {}; 
sizeof(Y) >= 1 

因此,即使類X本身佔用1個字節,這不會被翻譯成父類。所以從Y的角度來看,X類佔用了0個字節。

所以在這裏我們可以說編譯器已經優化了基類(儘管從技術上說它沒有做任何事情,我們只需要強制執行沒有對象具有零尺寸的規則)。

int main() 
{ 
    std::cout << sizeof(X) << ":" << sizeof(Y) << "\n"; 
} 

生成以下的輸出:

> ./a.exe 
1:1 
> 

原因一類的尺寸必須大於零是讓每一個對象的地址是唯一的。如果編譯器允許一個類的大小爲零,那麼存在多個變量(對象)都具有相同內存地址(因爲它們都具有零大小)的潛在的容易錯誤。解決這個潛在問題的簡單規則是所有對象都必須具有非零大小。

摘要:

size_of_type(X) = size_of_type(base) + sum(size_of_type(members)) + padding + (extra stuff like vtable pointer etc); 


sizeof(<CLASS>) = min(1, size_of_type(<CLASS>)) 
相關問題