静态数据成员初始化顺序

时间:2011-12-02 21:29:29

标签: c++

在单个翻译单元中考虑以下代码:

class C {
private:

    struct Init {

        Init() {
            /* compute data once here */
        }
    };
    static const Init& i;
    static int data[];
public:
    /* interface for reading data */
};

const C::Init& C::i = Init();
int C::data[200];
  1. C :: i总是在C :: data之后初始化,无论两者的定义顺序如何?
  2. 这个解决方案一次是计算静态数据最优雅的吗?

3 个答案:

答案 0 :(得分:6)

int C::data[200] 零初始化,这意味着静态初始化。静态初始化在动态初始化之前。由于C::Init::Init()不是常量表达式,因此动态初始化C::i C::data之后必须

详见3.6.2。

盗版报价:

  

具有静态存储持续时间的变量[...]应在任何其他初始化发生之前进行零初始化。 [...]一起,零初始化和常量初始化称为静态初始化;所有其他初始化是动态初始化。在进行任何动态初始化之前,应执行静态初始化。

答案 1 :(得分:0)

C::data未在那里初始化,因此顺序并不重要。

较短的解决方案是使用静态函数和虚拟变量:

class C {
private:

    static void Init() {
        /* compute data once here */
    }

    static bool data_init_helper;
    static int data[];
public:
    /* interface for reading data */
};

bool C::data_init_helper = (C::Init(), false);
int C::data[200];

答案 2 :(得分:0)

  

C :: i总是在C :: data之后初始化,无论顺序如何   两者的定义?

如果订单在同一编辑中定义,则保证订单 单位,否则不是。

  

这个解决方案一次是计算静态数据最优雅的吗?

没有。如果你真的必须让它静态,那么更好的方法(并防止可能的静态初始化命令惨败)是这样做的:

struct someDataStr
{
  int data[200];
};
someDataStr& AccessData()
{
  static someDataStr *ptr = NULL;
  if ( NULL == ptr )
  {
    ptr = new someDataStr;
    // initialize value
  }
  return *ptr;
}

如果它不必是静态的,那么使用依赖注入,并使用它将包含数据的对象传递给所有类。