2017-08-09 47 views
9

我最近在代码审查中遇到了这个与C++静态初始化相关的查询。初始化该类的静态对象的初始化之前是否保证了类的静态成员的初始化?

  1. 我和静态成员变量类编译单元
  2. 我在不同的编译单元

这里使用一个构造函数,类的静态对象,我想知道静态成员变量是否保证在静态对象构造函数被调用之前被初始化?

MyClass.h

typedef int (*MyFunc)(int); 
class MyClass { 
MyClass(MyFunc fptr) { 
    mFunc = fptr; 
} 
static MyFunc mFunc; 
} 

MyClass.cpp

MyFunc MyClass::mFunc = nullptr; 

MyDifferentClass.h

MyDifferentClass { 
public: 
    static int MyStaticFunc(int); 
} 

MyDifferentClass.cpp

static MyClass myClassObj(MyDifferentClass::MyStaticFunc); 

在代码中,将mFunc被初始化为nullptrmyClassObj之前被创造出来的?查询的原因是,如果订单不能保证,那么mFunc可能会重新初始化为nullptr

+0

没有理由容忍未知,也不会将其留给链接器。只需在main()的早期使用显式代码来确保序列。 –

回答

6

在代码中,将mFunc被初始化为nullptrmyClassObj之前被创造出来的?查询的原因是,如果订单不能保证,那么mFunc可能会重新初始化为nullptr

该问题的答案是“是”。

抛开线程指定对象的初始化问题,非局部变量的初始化按以下顺序执行。

  1. 所有变量都是零初始化的(未指定顺序)。这被称为零初始化
  2. 所有可以使用常量值初始化的变量都被初始化。这称为不断初始化

那些(上述1和2)被称为静态初始化

之后,执行动态初始化。

在你的情况,MyClass::mFunc使用常数初始化myClassObj使用动态初始化初始化初始化。因此,前者保证首先被初始化。

有关此主题的更多信息,请访问https://timsong-cpp.github.io/cppwp/n3337/basic.start.init

+1

由于各种原因,您正在引用C++ 11,但引用了很多[basis.start因缺陷报告2026](https://stackoverflow.com/a/34276374/1708801)而更改。所以要小心。 –

+0

@ShafikYaghmour,谢谢。这是很好的信息。 –