我在一个位域中塞满了一堆属性来节省空间:
struct Flags {
uint access : 2;
uint status : 2;
uint isEnabled : 1;
uint isDeletable: 1;
...
};
然后我有一个静态Flags defaultFlags
,它在程序启动时初始化。我的主要问题是对象构造函数中flags = defaultFlags;
是否安全,为了消除20行分别分配每个字段?
另外,我想知道序列化怎么样?根据编译器,Flags
是4个字节,我可以将其序列化为32位无符号整数并在没有任何数据损坏的情况下对其进行消毒吗?
答案 0 :(得分:3)
我的主要问题是flag = defaultFlags是否安全;在里面 对象构造函数,以消除20行分配 每个领域单独?
是。 Flags
的隐式定义的复制构造函数将适当地分配每个Bitfield。 [class.copy] / 15:
以这种方式复制/移动每个基本或非静态数据成员 适合其类型:
- 如果成员是数组,[..]
- 如果会员
m
具有右值参考类型T&& [..]- 否则,基础或成员使用相应的基数或
x
成员进行直接初始化。
我可以将其序列化为32位无符号整数并将其去除 没有任何数据损坏?
如果使用相同的编译程序在同一台机器上编写和读取文件,是的。但是,其他编译器或体系结构的布局可能不同,标准在这方面没有强加任何固定的要求。 [class.bit] / 1:
类对象中位域的分配是 实现定义。位域的对齐是 实现定义。比特字段被打包成一些可寻址的字段 分配单位。 [注意:比特字段跨越分配单元 一些机器而不是其他机器。位字段从右到左分配 在某些机器上,从左到右在其他机器上。 - 结束记录]
如果将其写入大小为char
的{{1}}数组,请将其写入文件并再次从中提取,将其复制回sizeof Field
对象应该会给您相同的价值观。 [basic.types] / 2(强调我的):
对于任何简单的对象(基类子对象除外) 可复制类型
Field
,无论对象是否包含有效的类型值T
,可以复制构成对象的基础字节(1.7) 成为T
或char
的数组。如果的内容 将unsigned char
或char
的数组复制回对象中 对象随后应保持其原始值。
然而,正如评论中所指出的,使用位掩码可以实现完全的可移植性(和合理的效率)。