C++ C++;在这种情况下你会怎么做?
在我正在工作的一个类中,我在头文件中发现了如下内容:C++ C++;在这种情况下你会怎么做?,c++,unions,C++,Unions,在我正在工作的一个类中,我在头文件中发现了如下内容: // Flags union { DWORD _flags; struct { unsigned _fVar1:1; unsigned _fVar2:1; unsigned _fVar3:1; unsigned _fVar4:1; }; }; 在类的一些成员函数中
// Flags
union
{
DWORD _flags;
struct {
unsigned _fVar1:1;
unsigned _fVar2:1;
unsigned _fVar3:1;
unsigned _fVar4:1;
};
};
在类的一些成员函数中,我看到\u flags
被直接设置为\u flags=3代码>。
我还看到了直接设置结构中的成员,比如\u fVar1=0
,并与之进行比较
我正在尝试删除\u fVar1
,我不确定它会对访问或设置\u标志
和其他\u fVar1
的其他地方做什么。
例如,设置\u flags=3
是否意味着\u fVar1
和\u fVar2
将为1,\u fVar3
和\u fVar4
将为0?删除或添加到结构是否意味着我必须对涉及联盟中任何其他成员的代码进行相应的更改?它没有什么特别之处。这只是一个整数变量和一个带位字段的结构的并集
结构中的每个位字段是一个位长,因此它可以用来访问整数中的单个位。
匿名成员结构(类)在C++中是不允许的,因此程序在标准方面是不正确的。
访问联合的非活动成员具有未定义的行为
简而言之:它所做的一切都取决于编译器
两个都允许在C中(前者不允许直到C11,后者直到C99),而一些编译器则作为C++的扩展(以及C的早期版本的扩展)。让我们假设您使用这样的编译器
例如,设置\u flags=3
是否意味着\u fVar
1和\u fVar2
将为1,\u fVar3
和\u fVar4
将为0
这可能就是我们的意图。但是,行为取决于编译器为位字段选择的表示形式
在不对表示进行假设的情况下,唯一可以使用union的明智做法是将所有标志设置为0(\u flags=0
),或将所有标志设置为1(\u flags=-1
)
删除或添加到结构是否意味着我必须对与联盟中任何其他成员相关的代码进行相应的更改
是的,除非代码平等地涉及到所有成员,如上面的两个示例。从技术上讲,访问工会的非活动成员是UB的,而C的类型双关语是合法的。听起来你需要读一本好书,向你解释什么是工会,因为现在你似乎没有掌握它。也许在这里开始:这不是有效的C++。意图是避免使用<代码>定义FLAG0x01 0< /COD> ETCA复杂度,我们必须检查特定的编译器,使用了<代码>未签名< /COD>的位。该标准规定“类对象中位字段的分配由实现定义。位字段的对齐由实现定义。位字段打包到某个可寻址的分配单元中。[注:在某些机器上,位字段跨越分配单元,而在其他机器上则没有。位字段在某些机器上从右向左分配,在其他机器上从左向右分配。-结束注]”.不太可靠…这在形式上是正确的,但我想说你也应该解释一下代码是如何工作的。如果我从@Bo Persson的评论中正确理解了它,那么在不了解更多编译器的情况下,_fVar1可能也是最重要的一位,对吗?@tuzzer正确。使用union需要s关于实施细节的假设。