【问题标题】:Problems with nested struct constructor and Union嵌套结构构造函数和联合的问题
【发布时间】:2012-07-17 09:49:20
【问题描述】:

我有一个嵌套在一个类中的结构和该结构的一个联合。如果我有一个带参数的结构构造函数,那么联合将不会编译。

我还想使用参数创建结构的实例。那条线也失败了。

class test
{
public:
test(void);
~test(void);

struct dtType {
    // inline constructors with initialisation lists
    dtType() : mins(0), hrs(0),day(0),mnth(0),year(0),DPOffset(0),DTType(0) {}
    dtType(byte z) : mins(z), hrs(z),day(z),mnth(z),year(z),DPOffset(0),DTType(0) {}
    dtType(byte n,byte h, byte d, byte m, byte y, byte o, byte t) : mins(n), hrs(h),day(d),mnth(m),year(y),DPOffset(o),DTType(t) {}

    // overloaded operator functions
    bool operator< (dtType date){return true;};
    bool operator<= (dtType date){return true;};
    bool operator> (dtType date){return true;};
    bool operator>= (dtType date){return true;};
    bool operator== (dtType date){return true;};

    // data members
    unsigned mins: 3;
    unsigned hrs: 5; // 8 bits
    unsigned day: 5; 
    unsigned mnth: 4;
    unsigned year: 7; // 16 bits
    unsigned DPOffset: 6; 
    unsigned DTType  : 2;
};

// if I comment out the union it compiles, otherwise I get:
// error C2620: member 'test::dtUnion::dt' of union 'test::dtUnion' has user-defined  constructor or non-trivial default constructor

union dtUnion { 
    dtType dt;
    unsigned long dtLong; // 32 bits
} dtU;

// if I call dtType judgement_day(); it compiles. Otherwise I get:
dtType judgement_day(1); // error C2059: syntax error : 'constant'

};

按照下面的答案,我现在尝试了以下方法,但出现错误 C2438:judgement_day,dateMask,timeMask : cannot initialize static class data via constructor

class test
{
public:
    test(): judgement_day(1),dateMask(1,1,1,1,1,0,0),timeMask(1,1,0,0,0,0,0){}
~test();
public:
struct dtType {
    // inline constructors with initialisation lists
    dtType() : mins(0), hrs(0),day(0),mnth(0),year(0),DPOffset(0),DTType(0) {}
    dtType(byte z) : mins(z), hrs(z),day(z),mnth(z),year(z),DPOffset(0),DTType(0) {}
    dtType(byte n,byte h, byte d, byte m, byte y, byte o, byte t) : mins(n), hrs(h),day(d),mnth(m),year(y),DPOffset(o),DTType(t) {}
    // overloaded operator functions
    bool operator< (dtType date){return true;};
    bool operator<= (dtType date){return true;};
    bool operator> (dtType date){return true;};
    bool operator>= (dtType date){return true;};
    bool operator== (dtType date){return true;};
    // data members
    unsigned mins: 3;
    unsigned hrs: 5; // 8 bits
    unsigned day: 5; 
    unsigned mnth: 4;
    unsigned year: 7; // 16 bits
    unsigned DPOffset: 6; 
    unsigned DTType  : 2;
};
const static dtType judgement_day;
const static dtType dateMask;
const static dtType timeMask;
};

【问题讨论】:

    标签: c++ struct nested unions


    【解决方案1】:

    标准不允许 union 具有显式构造函数的成员,这与 union 是成员或嵌套类型无关。

    以下内容也将无法编译:

    struct X
    {
        X() {};
    };
    union Y
    {
        X k;
    };
    

    【讨论】:

    • C++98 不允许具有非平凡构造函数或析构函数的成员(显式与它无关)。 C++11 允许这样的成员,但是有点麻烦——见stackoverflow.com/a/9547181/113662
    【解决方案2】:

    其他人已经回答了关于工会的问题;它不能包含具有非平凡默认构造函数的成员。回答第二个问题,关于成员初始化:

    你不能在类定义中初始化非静态成员;它们必须在构造函数的初始化列表中进行初始化:

    class test {
        // stuff
        dtType judgement_day;
    };
    
    test::test() : judgement_day(1) {}
    

    dtType judgement_day(); 编译的原因是它声明了一个函数,而不是一个变量。

    更新:由于您实际上希望这些成员是静态的,因此它们会在源文件中初始化,类似于全局变量:

    // in the header
    class test {
        // stuff
        const static dtType judgement_day;
    };
    
    // in exactly one source file
    const test::dtType dtType::judgement_day(1);
    

    【讨论】:

    • 我真正想要的是一些 dtType 的 const 实例,它们具有不同的值作为掩码。 const 必须在创建时初始化。我该怎么做?
    • @user1531175:就这样。您可以在构造函数的初始化列表中初始化const 成员。
    • 我尝试了以下无法编译的方法:Err cannot initialize static class data via constructor class test { public: test():judgement_day(1),dateMask(1,1,1,1, 1,0,0),timeMask(1,1,0,0,0,0,0){} ~test(); public: struct dtType { dtType(byte z) : mins(z), hrs(z),day(z),mnth(z),year(z),DPOffset(0),DTType(0) {} dtType(byte n,byte h, byte d, byte m, byte y, byte o, byte t) : mins(n), hrs(h),day(d),mnth(m),year(y),DPOffset(o) ,DTType(t) {} ... }; const static dtTypejudgement_day;常量静态 dtType 日期掩码; const static dtType timeMask; ;
    • 哇!那最终没有可读性!请查看我在第一篇文章中添加的附加代码。
    • @user1531175:静态成员不同;由于它们不与任何对象关联,因此您无需在对象的构造函数中初始化它们。相反,您可以在源文件中初始化它们,例如全局变量,例如const test::dtType test::judgement_day(1);。你仍然需要在类中声明它们,就像你的代码一样。
    【解决方案3】:

    联合不能包含类实例。考虑一个包含两个对象的联合,在创建联合时应该调用哪个构造函数?编译器不能同时调用这两个构造函数,因为这可能会导致一个对象包含错误的值。

    【讨论】:

    • 如果它们是 POD,它可以包含对象。
    【解决方案4】:

    只要联合包含dtType 成员,那么dtType 就不能有构造函数。

    但是,您可以将构造函数更改为 void Set() 函数,以便在构造后隐式调用。

    例如:

    int main()
    {
        test::dtType judgement_day;
        judgement_day.Set(1);
    
        test::dtUnion x;
        x.dt.Set(1);
    
        assert(judgement_day == x.dt);
        return 0;
    }
    

    【讨论】:

    • 谢谢。为什么 test::dtTypejudgement_day = {1,1,1,1,1,0,0};在 main() 中不编译?我以为你可以用花括号列表初始化结构。
    • @user1531175 只有在没有提供构造函数的情况下才能这样做。在这种情况下,7 参数构造函数是更好的初始化方式。 [请记住对任何对您有用的答案进行投票。]
    • 感谢您的解释。我想投票给你的答案,但这是我的第一篇文章,我还没有很好的声誉!
    猜你喜欢
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    相关资源
    最近更新 更多