【问题标题】:Initialization of static data member静态数据成员的初始化
【发布时间】:2014-09-01 04:06:28
【问题描述】:

为什么不发生静态数据成员的默认初始化?在下面的例子中

struct data_member
{
    data_member(){ cout << "data_member\n"; }
    ~data_member(){ cout << "~data_member\n"; }
};

struct Y
{
    static data_member m;
    Y(){ cout << "Y\n"; }
    ~Y(){ cout << "~Y\n"; }
};

Y y; //call constructor of Y 

但如果我们从data_member m 中删除static 说明符,它将被默认初始化。

struct data_member
{
    data_member(){ cout << "data_member\n"; }
    ~data_member(){ cout << "~data_member\n"; }
};

struct Y
{
    data_member m;
    Y(){ cout << "Y\n"; }
    ~Y(){ cout << "~Y\n"; }
};

Y y; //call Y() and data_member()

【问题讨论】:

  • 因为您没有提供m 的定义。
  • @CaptainObvlious 9.4.2/6:静态数据成员的初始化和销毁​​与非局部变量完全一样。这意味着必须执行默认初始化。
  • 完全正确,只要你为它提供一个你没有做过的定义。
  • @CaptainObvlious 为什么非静态数据成员初始化?
  • @DmitryFucintv 非静态成员显然需要在构造对象时构造。静态成员声明不会导致构造,因为它只是声明成员的存在。

标签: c++ storage-duration


【解决方案1】:

静态成员必须在类定义之外定义。届时会被初始化(也可以默认初始化)。

标准草案中关于static成员变量的以下描述应该解释为什么它没有在类声明中默认初始化。

9.4.2 静态数据成员

2 static 数据成员在其类定义中的声明不是定义,并且可能是除 cv-qualified void 之外的不完整类型。 static 数据成员的定义应出现在包含该成员的类定义的命名空间范围内。在命名空间范围的定义中,static 数据成员的名称应使用 :: 运算符由其类名限定。

【讨论】:

    【解决方案2】:
    struct Y
    {
        static data_member m;
        Y(){ cout << "Y\n"; }
        ~Y(){ cout << "~Y\n"; }
    };
    

    这只是声明m。就编译器所知,Y::m 是在另一个翻译单元中定义的。由于静态数据成员是每个类一个,因此您必须能够在不定义它们的情况下声明它们,否则您将无法将类定义放在头文件中而不会在包含头文件时违反单一定义规则不同的翻译单元。

    data_member Y::m;
    

    这定义了 m 和 will cause a constructor call

    【讨论】:

      【解决方案3】:

      static 数据成员在class 定义中声明。它们需要在此之外定义(一次),通常在相应的cpp 文件中:

      data_member Y::m;
      

      这是您将看到它被调用的默认 ctor 的地方。

      【讨论】:

        【解决方案4】:

        基本答案: 对于类成员,就像使用函数一样。 我们有声明和定义。 您“声明”它们的存在@class 级别并且“定义”由构造函数进行。 使用静态成员更复杂。它们不是“实例相关的”,构造函数不会“定义”它们。你必须在课外自己做:

        Type CLASS::member;
        

        顺便说一句,使用静态成员是非常糟糕的做法。

        改用静态函数:

        class Foo{
        public:
             Type &getMember(){
                 static Type member;
                 return member;
             }
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-18
          • 1970-01-01
          • 1970-01-01
          • 2011-12-02
          相关资源
          最近更新 更多