可以在C ++类中使用位字段吗?

时间:2016-11-17 12:40:46

标签: c++ class bit-fields

在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大小。

3 个答案:

答案 0 :(得分:8)

是的,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包含您需要的所有信息:

  

constant-expression应为具有大于或等于零的值的整数常量表达式。 整数常量表达式的值可能大于位字段类型的对象表示(3.9)中的位数;在这种情况下,额外的比特用作填充比特,不参与比特字段的值表示(3.9)。类对象中的比特字段的分配是实现定义的。位字段的对齐是实现定义的。比特字段被打包到一些可寻址的分配单元中。 [注意:位字段跨越某些机器上的分配单元而不是其他机器上的分配单元。在某些机器上从右到左分配位字段,在其他机器上从左到右分配。 - 后注]

强调我的

从这里我们得到bit-feild的大小至少是底层数据类型的大小,但是如果你过度分配空间那么额外的空间就变成了padding而不用于bit的值-field成员。

答案 1 :(得分: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

中的位字段

答案 2 :(得分:0)

作为实施质量(QoI)的问题,是的,成员的大小实际上是我所知道的所有编译器的指定大小。

如果您询问尺寸是否必须匹配(根据标准),您必须问自己如何辨别? (以标准的符合方式。)如果你不能(我认为你不能),那么在as-if规则下,编译器可以做它喜欢的事情。

有关详细信息,请参阅C++14 standard(实际上是n4296。)

的第9.6节