2016-11-17 16 views
5

在C的結構,所以能夠指定不同於類型的默認位長度這樣另一個位長度:可以在C++類中使用位字段嗎?

struct MyStruct{ 
    int myVar : 1; //Size of myVar is 1 bit (so it can take values 0 or 1 
    int myOtherVar: 4; //Size of myOtherVar is 4 bits (so it can take values 0 to 15) 
} 

這就是所謂的位字段。

我的問題是,如果它也可以做到這一點的C++類,像這樣:

class MyClass{ 
    public: 
     //Some methods 
    private: 
     int m_myAttribute : 1; 
     int m_myOtherAttribute : 4; 
} 

我搜索了這個網站,但我所有的例子中使用的結構,而不是類位字段。

我測試了這段代碼,它編譯得很好,但是我想知道屬性的大小是否真的是指定的大小,或者編譯器是否忽略了這些位域並使用了標準大小的int大小。

+1

這不會回答你的問題,但可能是相關的:http://stackoverflow.com/questions/3319717/is-there-a-bit-equivalent-of-sizeof-in-c –

+0

你可以檢查它'sizeof ()'功能。另外,就我所知,結構和類之間的唯一區別是,默認類變量將是** private **,默認結構變量將是** public **。您應該閱讀這裏:[http://stackoverflow.com/a/7762179/1867076] – Prometheus

+2

C++中的類幾乎在所有方面都與結構相同。 ** only **區別是默認訪問說明符(對於類 - 私有,對於結構體 - 公共) –

回答

8

是的a class可以有位字段成員。在C++中,classstruct之間沒有區別,默認訪問級別和默認繼承類型除外。它們都被稱爲類類型。如果你可以在struct中做點什麼,那麼你可以在class中做同樣的事情。由於默認訪問級別不同,它們看起來會有點不同,但您會得到同樣的結果。例如

struct foo 
{ 
    int m_myAttribute : 1; 
    int m_myOtherAttribute : 4; 
    int m_myOtherOtherAttribute : 27; 
}; 

相同

class bar 
{ 
public: 
    int m_myAttribute : 1; 
    int m_myOtherAttribute : 4; 
    int m_myOtherOtherAttribute : 27; 
}; 

確實注意到,雖然我們曾在類中使用public:,因爲默認情況下,成員是私有的。

現在關於C++中位字段的大小。 [class.bit]/1具有您需要的所有信息:

常量表達式應該是一個整數常量表達式,其值大於或等於零。 積分常數表達式的值可能大於比特字段類型的對象表示(3.9)中的比特數;在這種情況下,額外的比特被用作填充比特並且不參與比特字段的值表示(3.9)。類對象內位字段的分配是實現定義的。位字段的對齊是實現定義的。位字段被打包成一些可尋址的分配單元。 [注意:位域跨越某些機器上的分配單元,而不是其他機器上的分配單元。位字段在某些機器上從右向左分配,在其他機器上從左向右分配。末端注]

重點煤礦

由此我們得到了位費爾德的大小將是底層數據類型的至少大小,但如果你在分配空間,那麼額外的空間變成填充並且不用於位域成員的值。

+1

'默認訪問級別*和默認繼承類型*除外,儘管此處未使用。 – Ruslan

+0

@Ruslan更新。 – NathanOliver

+0

當你說這兩個代碼是相同的,你的意思是編譯的代碼是完全相同的,或只是他們做同樣的事情? –

0

作爲執行質量(QoI)的問題,是的,成員的大小真的是我知道的所有編譯器的指定大小。

如果你問大小是否必須匹配(根據標準),你必須問自己如何分辨? (以標準符合的方式)。如果你不能(我認爲你不能),那麼在as-if規則下,編譯器可以做它喜歡的事情。

有關更多細節,參見C++14 standard的部分9.6(實際上n4296。)

2

它是用C完全合法++使用具有類或結構位字段。我還建議這一問題進一步深入的相似點和兩個區別:What are the differences between struct and class in C++?

而且是位大小是真正考慮到了,只記得內存佈局的大小取決於實現

class test { 
    int a : 3; 
    void fun() { 
     // std::cout << sizeof(a); // Illegal (*) 
     a = 5; // Warning! Implicit truncation from int to 3-bit bitfield yields -3 (2's complement) 
    } 
}; 

int main() { 
    std::cout << sizeof(test); // ABI-dependent, might be 4 bytes 
} 

(*)我再來談談關於使用sizeof與位域的您的評論:這是允許在一個glvalue指定位字段使用sizeof作爲[expr.sizeof]/p1

相關問題