C++ 位域

类和结构可包含比整型类型占用更少存储空间的成员。 这些成员被指定为位域。 位域成员声明符规范的语法如下

语法

declarator:constant-expression

注解

(可选)declarator 是在程序中访问成员的名称。 它必须是整型类型(包括枚举类型)。 constant-expression 指定结构中成员所占据的位数。 匿名位域—即不带标识符的位域成员—可用于填充。

注意

宽度为 0 的未命名位域强制将下一个位域与下一个类型边界对齐,其中类型是成员的类型。

下面的示例声明包含位域的结构:

// bit_fields1.cpp
// compile with: /LD
struct Date {
   unsigned short nWeekDay  : 3;    // 0..7   (3 bits)
   unsigned short nMonthDay : 6;    // 0..31  (6 bits)
   unsigned short nMonth    : 5;    // 0..12  (5 bits)
   unsigned short nYear     : 8;    // 0..100 (8 bits)
};

Date类型的对象的概念上的内存布局如下图所示:

Diagram of the memory layout of a date object, showing where the n WeekDay, n MonthDay, n Month, and n Year bit fields are located.

32 位内存显示在一行中。 从最小有效位开始,3 位用于 nWeekDay。 接下来的 6 位用于 nMonthDay。 接下来的 5 位用于 nMonth。 接下来的 2 位未使用。 接下来的 8 位用于 nYear。 其余 8 位未使用。

nYear的长度为 8 位,这会溢出声明类型unsigned short的字边界。 因此,它始于新unsigned short的开头。 并不必使所有位域均适合基础类型的对象;根据声明中请求的位数来分配新的存储单元。

Microsoft 专用

声明为位域的数据从低位到高位进行排序,如上图所示。

结束 Microsoft 专用

如果结构的声明包含长度为 0 的未命名字段(如以下示例所示):

// bit_fields2.cpp
// compile with: /LD
struct Date {
   unsigned nWeekDay  : 3;    // 0..7   (3 bits)
   unsigned nMonthDay : 6;    // 0..31  (6 bits)
   unsigned           : 0;    // Force alignment to next boundary.
   unsigned nMonth    : 5;    // 0..12  (5 bits)
   unsigned nYear     : 8;    // 0..100 (8 bits)
};

则内存布局如下图中所示:

Diagram of the layout of a Date object, with a zero length bit field, which forces alignment padding.

64 位内存显示在一行中。 从最小有效位开始,5 位用于 n 个月。 接下来的 8 位用于 n 年。 接下来的 19 位未使用。 接下来的 3 位用于 n 个工作日。 接下来的 6 位用于 n 个 MonthDay。 其余位未使用。

位域的基础类型必须是整数类型,如内置类型中所述。

如果对类型const T&的引用的初始值设定项是引用类型为T的位域的 lvalue,引用不会直接绑定到位域。 相反,引用会绑定到一个临时初始值设定项以保留位域的值。

位域的限制

以下列表详述了位域的错误操作:

  • 采用位域的地址。

  • 使用位域初始化非 const 引用。

另请参阅

类和结构