我很惊讶这不起作用:
union DlDatum
{
float mFloat;
s32 mInteger;
};
class DlDbE
{
public:
DlDbE( float f ) : mData.mFloat( f ) {};
private:
DlDatum mData;
};
有没有办法在c ++构造函数mem-initializer列表中初始化union?
更新:答案是为union创建构造函数。不知道可以做到的。这是我做的:
union DlDatum
{
float mFloat;
s32 mInteger;
bool mBoolean;
u32 mSymbol;
u32 mObjIdx;
DlDatum( ) : mInteger( 0 ) {}
DlDatum( float f ) : mFloat( f ) {}
DlDatum( s32 i ) : mInteger( i ) {}
DlDatum( bool b ) : mBoolean( b ) {}
DlDatum( u32 s ) : mSymbol( s ) {} // this ctor should work for objIdx also
};
class DlDbE
{
public:
DlDbE() {}
DlDbE( float f ) : mData( f ) {}
DlDbE( u32 i ) : mData( i ) {}
DlDbE( bool b ) : mData( b ) {}
...etc..
private:
DlDatum mData;
};
答案 0 :(得分:14)
在C ++ 03中,在你开始为你的联盟编写构造函数之前。
在C ++ 11中,统一初始化将聚合初始化的语法扩展到构造函数初始化列表。这意味着好的旧聚合初始化器语法如
DlDatum d = { 3.0 };
我们都知道并喜欢来自C并且初始化了union的第一个成员,现在也可以在构造函数初始化列表中使用
union DlDatum
{
float mFloat;
s32 mInteger;
};
class DlDbE
{
public:
DlDbE( float f ) : mData{f} {}
private:
DlDatum mData;
};
此功能仅允许您“定位”联合的第一个非静态成员以进行初始化。如果你需要更灵活的东西,那么它又回到编写构造函数。
答案 1 :(得分:13)
与任何其他成员一样,如果你想构建一个union,你必须给union一个构造函数并调用它。
答案 2 :(得分:3)
@AndreyT给出了一个很好的答案,我将通过一些实用的建议进行扩展。
我倾向于使用联合,以便轻松访问位图值,而无需繁琐和丑陋的按位和/或按位或。我认为这是一种相当普遍的做法。
我使用了一段时间使这个过程更容易的技术是,如果我使用的是小于32位的位图,我将其声明为 union <中的未命名的 struct / em>以及随附的 DWORD 数据成员。例如:
union UNICODECONTROL{
DWORD dwAccessor;
struct{
unsigned unicode_01 : 1;
unsigned unicode_02 : 1;
unsigned unicode_03 : 1;
unsigned unicode_04 : 1;
unsigned unicode_05 : 1;
unsigned unicode_06 : 1;
unsigned unicode_07 : 1;
unsigned unicode_08 : 1;
unsigned unicode_09 : 1;
unsigned unicode_10 : 1;
};
};
随着它的到位,它将像'访问者'功能一样工作。如果要设置值,可以通过为此“访问者”分配带有相应位图的数字来一次性完成。你想把它们全部归零 - 也是一块蛋糕。它特别适用于Windows注册表。为了存储union位图的值,您只需将 DWORD 写入注册表即可!稍后检索它以进行重新初始化同样很简单。
DWORD 是注册表的本机类型之一,您无需乱搞静态转换或编写手动转换函数。如果你有一个比32位更长的位图你可以声明一个64位大小的整数,它通常会以相同的方式工作 - 同样适用于注册表,因为 QUADWORD 也是一个本机类型。 / p>
这直接关系到@AndreyT提到的内容 - 如果你想在我的union-bitmap / DWORD 格式中方便地初始化类数据成员,你所要做的就是 - 就像在示例 - 确保'accessor'是union中声明的第一个值。然后,您可以使用新的C ++ 11'{}'方案直接对其进行mem-list。根本不需要奇怪的工会构造者!
警告。如果单独的位图位位于“内部”,则访问器DWORD将取决于结构的对齐设置。这是在编译器级别或MSVC ++中的__declspec(align(#))
语句以及其他编译器中的类似语法中设置的。
最后,最近在几个不同的场景中尝试了这些想法时学到了更新。尽管C ++ 11明确表示如上所述通过其第一个变量初始化union是合法的,但MSVC ++似乎忽略了这个标准 - 或者“未实现”它作为编译器错误输出状态。因此,如果您要使用Microsoft编译器,则必须为联合实现一个混乱的构造函数,如果您想要初始化它。遗憾的是,可能符合C ++ 11标准将进一步改进VS2013的服务包以及整个IDE的下一次2014迭代。