何时以及如何在C ++中初始化静态数据?

时间:2011-10-27 23:27:36

标签: c++ class static constructor initialization

何时初始化静态数据?

我想:

可以通过初始化 构造函数,

宣布时,

以外的课程
class A::member_d = 5; //  member_d is static  
其他人?

此外,何时初始化文件范围静态变量以及何时执行函数范围静态变量initizliaed?

我认为他们在宣布时会被初始化。

感谢

4 个答案:

答案 0 :(得分:4)

类的静态成员在定义时初始化。 Const积分数据类型是一个可以在声明点初始化的异常。当要执行这样的初始化有点复杂时(google for static initialization fiasco )。根据标准:

  

如果初始化延迟到第一个main语句之后的某个时间点,它应该在第一次使用与要初始化的变量相同的转换单元中定义的任何函数或变量之前发生。

答案 1 :(得分:2)

静态存储持续时间对象初始化:

注意:静态成员对象的初始化方式与文件范围内的对象相同。

  • 文件范围内的对象在定义点初始化。
    • 您可以将这些视为在调用main()之前初始化所有内容。
    • 详情请见下文。
  • 函数作用域中的对象在第一次执行时通过定义进行初始化。
    • 即通常是第一次调用该函数。

该对象由定义中的初始化程序初始化。如果你不提供初始化程序,那么它将被零初始化。

int x1;        // zero initialized.
int x2 = 5;    // initialized with 5 
A   y1;        // Default initialized:
               // If A has a user defined constructor this is called.
               // If A has a compiler generated constructor then
               // it is value-initialized which means class objects have their
               // default constructor called and POD objects are zero-initialized
A   y2 = A();  // Default constructed.
A   y3(5);     // Constructor called with value 5.

静态成员与文件范围的对象完全相同。

class Z
{
    static int x1; // declaration;
    static int x2;
    static A   y1;
    static A   y2;
    static A   y3;
};
// definition

int Z::x1;
int Z::x2 = 5;
A   Z::y1;
A   Z::y2 = A();
A   Z::y3(5);

现在初始化它们的顺序很难定义。故意将订单模糊不清以允许委员会无法预见的编译器和链接器情况。

定义于:

3.6.2非局部变量的初始化

需要注意的主要事项是:

  

具有静态存储持续时间的非局部变量由于程序启动而初始化。

因此在大多数情况下,在输入main之前,它们都将完全构建。

正如其他人所说。允许编译器延迟初始化。

3.6.2第4段

  

实现定义了具有静态存储持续时间的非局部变量的动态初始化是否在main的第一个语句之前完成。

这个添加主要是为了支持在运行时动态加载库(可以在main启动后动态加载)。但它确实提供了一个简单的保证,即编译中的所有静态存储持续时间对象将在使用该编译中的任何对象或函数之前完全构造。

3.6.2第5段

  

如果初始化被延迟到线程初始函数的第一个语句之后的某个时间点,它应该在任何变量的第一个odr-use(3.2)之前发生,并且在同一个翻译单元中定义了线程存储持续时间作为要初始化的变量。

答案 2 :(得分:1)

全局变量在程序启动时初始化,在调用main()之前。范围本地的静态对象在第一次执行时通过它们进行初始化。

静态类成员只是全局变量,请参见上文。

main()返回后发生全局和静态对象的破坏。

(这个的实现细节是相当复杂的,因为所有的析构函数都必须在某处排队等待执行,对于本地静态,需要有一个标志来指示对象是否已经被实例化。)

答案 3 :(得分:0)

不,当然,构造函数无法初始化静态数据成员。对于const积分或枚举类型,您可以在类定义的范围内进行初始化。但是,通常,您必须在类定义之外进行初始化。