2012-02-06 63 views
9

我是C++新手,在C++中發現了一個特殊功能。我看到一個空的大小是1個字節,我做了一些研究,發現這是因爲每個對象都必須有一個獨特的地址。但我想知道這個1字節的內容是什麼。我知道它不保存「this」指針,但是它是一個虛擬字節還是實際上有一些內容?C++類空類的大小1字節

回答

11

沒有內容。這只是一個虛擬字節。

classstruct必須有其sizeof0更大,ERGO你的行爲。這是標準預期和要求的。

+0

其實在g ++中,可以定義一個具有0大小的類。看到我的答案。 – TrueY 2016-07-07 07:42:15

0

這是一個虛構的字節 - 構造函數和析構函數將是微不足道的,沒有「數據存儲」。

2

你可以使用你的調試器或類似printf("%x", *(unsigned char *)&myobj);的東西來查看字節的內容。我沒有閱讀C++規範,但我會猜想該字節的內容是未定義的,因此行爲取決於編譯器和您的操作系統。

3

該字節不包含任何內容,它在那裏使某些其他行爲更好。例如,考慮另一個包含空類的情況。

class Empty 
{ }; 

class TwoEmpties 
{ 
    Empty a; 
    Empty b; 
}; 

您可能希望兩個成員,&TwoEmpties::a&TwoEmpties::b,的地址是不同的。要發生這種情況,它們必須具有大於1的大小(或者編譯器必須在它們之間添加填充,這又會使編譯器何時何地向編譯器添加填充的規則複雜化。)

+0

不可否認**你經常需要兩位成員的地址。的確,在大多數情況下,你不關心兩位成員的地址。這條規則適用於少數用例,雖然它們被認爲足夠重要,可以授權它。 – 2012-02-06 09:13:51

+0

@MatthieuM。同意。修正了這個措辭 – 2012-02-06 09:35:41

7

它是強制的根據標準,相同類型的不同對象應該具有不同的地址。這又確保對於任何對象TT*充當該對象的明確標識符(對於該類型)。當然,你並不需要知道兩個對象是否真的是相同的,但有時(給定C++低級訪問)這是必要的,或者只是簡單的方便。

因此指定沒有對象應該具有空值大小。

有一個例外,雖然:使用空類作爲基類時,編譯器可以選擇適用空基地優化EBO)是某些情況下,例如:

struct Empty {}; 

struct Slim: Empty { 
    int a; 
}; 

static_assert(sizeof(Slim) == sizeof(int), ""); 

通常會添加基類的大小,但在這種情況下並不是必需的。然而,規則相同類型的兩個不同的對象不應該有相同的地址仍然適用,所以:

struct Fat: Empty { 
    Empty e; 
}; 

static_assert(sizeof(Fat) > sizeof(Empty), ""); 

EBO是在模板的情況下使用private繼承的主要原因。例如:

template <typename Allocator> 
class MyClass: private Allocator { 
}; 

這樣,如果事實證明,Allocator是一個空類,也不會有任何開銷。一般來說,它通常用於政策,例如您傳遞給map的謂詞。

1

empty class has a sizeof 1因爲當創建該類的對象時,如果size = 0,它們將被存儲在內存中的相同位置。

假設當你創建一個對象address is 1000

如果尺寸爲class is 0,則尺寸也爲object must be 0

(therefore, object is located at 1000+0=1000) 

所以,現在如果另一個對象由,

Add. of 2nd object=1000+0th location 

兩個對象具有相同的地址,這是不確定的行爲,一樣會有歧義,其對象被稱爲不應發生。

因此empty classes are given a byte of memory,以防止這種情況發生。

0

根據我的知識,上述所有答案都不正確。 正確答案是默認創建的類的對象時,4個內置函數被調用是

  1. 默認的構造

  2. 默認析構函數

  3. 複製構造

  4. 重載作業運營商

因此空類的大小是1字節, 示例:嘗試這個

#include<iostream> 
using namespace std; 
class Test 
{ 
}; 
int main() 
{ 
Test t; 
cout<< "size of empty class is "<<sizeof(t); 
} 
0

我面對類似的問題,似乎可以定義具有零長度的小動作的類。我不知道這是否僅僅是因爲G ++,但看到下面的代碼片段:

struct ONE {}; 
struct ZERO { char x[0]; }; 

int main() { 
    cout << sizeof(ONE) << ", " << sizeof(ZERO) << endl; 

    ONE* po1 = new ONE; 
    ONE* po2 = new ONE; 
    cout << po1 << ", " << po2 << endl; 

    ZERO* pz1 = new ZERO; 
    ZERO* pz2 = new ZERO; 
    cout << pz1 << ", " << pz2 << endl; 
} 

輸出是:

1, 0 
0xe4f010, 0xe4f030 
0xe4f050, 0xe4f070 

所以空類的大小是一個(根據C++標準),但是如果它只有一個長度爲零的數組字段,其大小就會變成零。如果在new的堆上分配了一個新的非零大小的類,則返回一個有效的地址,並且如果多次分配它們的指針指向不同的內存地址。

+0

好吧,一個靜態的零長度數組是不合格的。 – Deduplicator 2017-07-04 22:50:41

+0

@Deduplicator也許你是對的,但我已經看到過這樣的結構(char [0]作爲最後一項)。所以它以某種方式傳播。 – TrueY 2017-07-06 08:11:49

+0

struct int {int} length; char d [0]; }; 是變量記錄長度*技巧*(儘管我不喜歡調用任何如此強大的'技巧':))。 – 2017-09-16 14:16:08