如何在构造函数中初始化位域

5

如何在构造函数中初始化以下结构的值为定义好的值?

我的代码示例中显示的两个选项似乎都有点丑陋...

struct T_AnlagenInfo01
{   
    // Option A
    T_AnlagenInfo01() : fReserve80_0(0), fReserve80_1(0),.... {}; 

    // Option B
    T_AnlagenInfo01()
    { 
        memset(this, 0, sizeof(T_AnlagenInfo01));
    } 

    unsigned long fReserve80_0                          : 1;        
    unsigned long fReserve80_1                          : 1;        
    unsigned long fReserve80_2                          : 1;        
    unsigned long fReserve80_3                          : 1;        
    unsigned long fReserve80_4                          : 1;
    unsigned long fReserve80_5                          : 1;
    unsigned long fReserve80_6                          : 1;
    unsigned long fReserve80_7                          : 1;

    unsigned long fReserve81_0                          : 1;        // 81   
    unsigned long fReserve81_1                          : 1;        
    unsigned long fReserve81_2                          : 1;        
    unsigned long fReserve81_3                          : 1;
    unsigned long fReserve81_4                          : 1;
    unsigned long fReserve81_5                          : 1;
    unsigned long fReserve81_6                          : 1;
    unsigned long fReserve81_7                          : 1;
};

如果类中有虚函数,请小心使用memset的替代方法,因为它也会覆盖虚表。 - Some programmer dude
可怕的命名惯例。遗留问题,我猜?不管怎样, fReserve80_0(0)是标准方式,实际上比memset更清晰易懂,也更易于维护和类型安全。 - Sebastian Mach
@phresnel:哦,是的... :-( 遗留代码在新的更快的机器上使用时停止工作了。 - Ronald McBean
可能是如何使用C++构造函数初始化位域?的重复问题。 - Some Guy
3个回答

4

一个明显的解决方案是将所有位放在单独的结构中,该结构是您结构的成员,并从静态成员进行复制初始化,例如:

struct T_AnlagenInfo01
{
    struct Bits
    {
        unsigned long fReserve80_0 : 1;
        unsigned long fReserve80_1 : 1;
        //  ...
    };
    Bits myBits;
    static Bits initialBits;

    T_AnlagenInfo01 : myBits(initialBits) {}
};

T_AnlagenInfo01::Bits T_AnlagenInfo01::initialBits = {};

这甚至允许某些位具有与0不同的值。

2
我认为选项A并不那么糟糕。如果您同意为每个位使用不同命名的变量所带来的麻烦,那么请友好地单独初始化它们。选项B似乎是一种肮脏的hack,甚至可能是技术上未定义的行为(尽管我不完全确定)。无论如何,安全第一。想想看,很有可能它实际上是UB,因为您的类型不是POD
请注意,我的答案适用于如果您想为每个位使用不同命名的变量。您始终可以将std::vector<bool>std::bitset<N>boost::dynamic_bitset作为成员,而不是所有这些位域。

0

选项 C

struct T_AnlagenInfo01
{
   bitset<14> mybits;
}

你可以使用bitset代替位域,如果你想将它们全部设置为未设置状态,则无需进行任何特殊的初始化。而且,你可以提供成员函数来完成相同的工作,而不是使用一个具有14个成员的类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接