详细解读C++编程中的匿名类类型和位域

时间:2022-06-01 16:38:10

匿名类类型
类可以是匿名的 - 也就是说,可以在没有 identifier 的情况下声明类。在将类名称替换为 typedef 名称时,这会很有用,如下所示:

?
1
2
3
4
5
typedef struct
{
  unsigned x;
  unsigned y;
} POINT;

注意
上面示例中显示的匿名类的用法对于保留与现有 C 代码的兼容性很有用。在某些 C 代码中,将 typedef 与匿名结构结合使用是很普遍的。
如果您希望对类成员的引用就像它未包含在独立类中的情况一样出现,则匿名类也很有用,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
struct PTValue
{
  POINT ptLoc;
  union
  {
    int iValue;
    long lValue;
  };
};
 
PTValue ptv;

在上面的代码中,可以使用对象成员选定内容运算符 (iValue.) 访问 ,如下所示:

?
1
int i = ptv.iValue;

匿名类受某些限制的约束。(有关匿名联合的详细信息,请参阅联合。) 匿名类:
不能具有构造函数或析构函数。
不能作为函数的参数传递(除非使用省略号使类型检查无效)。
无法作为函数中的返回值返回。

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

?
1
declarator : constant-expression

备注
(可选)declarator 是在程序中访问成员的名称。它必须是整型类型(包括枚举类型)。 常数表达式指定结构中成员所占据的位数。匿名位域 — 即不带标识符的位域成员,可用于填充。
注意
宽度为 0 的未命名位域强制将下一个位域与下一个 type 边界对齐,其中 type 是成员的类型。
下面的示例声明包含位域的结构:

?
1
2
3
4
5
6
7
8
// 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 类型的对象的概念上的内存布局如下图所示。

详细解读C++编程中的匿名类类型和位域

数据对象的内容布局
请注意,nYear 的长度为 8 位,并且会溢出声明类型 unsigned short 的字边界。因此,它始于新 unsigned short 的开头。并不必使所有位域均适合基础类型的对象;根据声明中请求的位数来分配新的存储单元。
如果结构的声明包含长度为 0 的未命名字段(如以下示例所示),

?
1
2
3
4
5
6
7
8
9
// 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)
};

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

详细解读C++编程中的匿名类类型和位域

带有零长度位域的数据对象的布局
位域的基础类型必须是整型类型。