简体   繁体   English

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

[英]When and how are static data initialized in C++?

When are static data initialized ? 何时初始化静态数据?

I think: 我认为:

It can be initialized by constructor, 可以由构造函数初始化,

or 要么

when it is declared, 当它被宣布时,

or outside of the class by 或在课堂外

class A::member_d = 5; //  member_d is static  

others ? 其他 ?

Also, When do file scope static variables initialized and when do function scope static variables initizliaed? 另外,什么时候初始化文件作用域静态变量,什么时候初始化函数作用域静态变量?

I think they are initialized when they are declared. 我认为它们在声明时已初始化。

thanks 谢谢

Static members of a class are initialized at the point of definition. 类的静态成员在定义时进行初始化。 Const integral data types are an exception that can be initialized at the point of declaration. 常量整数数据类型是一个异常,可以在声明时进行初始化。 When such initialization is going to be executed is somewhat complicated (google for static initialization fiasco ). 当要执行此类初始化时,会有些复杂(google为静态初始化fiasco )。 According to the standard: 根据标准:

If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first odr-use of any function or variable defined in the same translation unit as the variable to be initialized. 如果将初始化推迟到main的第一条语句之后的某个时间点,则它应发生在与要初始化的变量在同一转换单元中定义的任何函数或变量的首次使用之前。

Static Storage duration object initialization: 静态存储持续时间对象初始化:

Note: Static member objects are initialized the same way as objects at file scope. 注意:静态成员对象的初始化方式与文件范围内的对象相同。

  • Objects at file scope are initialized at point of definition. 文件范围内的对象在定义点被初始化。
    • You can think of these as all being initialized before main() is called. 您可以将它们视为所有在调用main()之前初始化的对象。
    • See details below. 详情见下文。
  • Objects in function scope are initialized the first time execution passes over the definition. 函数范围内的对象在第一次执行通过定义时被初始化。
    • ie Usually the first time the function is called. 即通常是第一次调用该函数。

The object is initialized by the initializer in the definition. 该对象由定义中的初始化程序初始化。 if you do not provide an initializer then it will be zero-initialized. 如果您不提供初始化程序,那么它将被零初始化。

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.

Static members are exactly the same as objects as file scope. 静态成员与对象和文件作用域完全相同。

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);

Now the order that they are initialized is harder to define. 现在,很难初始化它们的顺序。 The order is deliberately left vague to allow for compiler and linker situations that the committee could not foresee. 该命令故意含糊不清,以允许委员会无法预见的编译器和链接器情况。

It is defined in: 它的定义是:

3.6.2 Initialization of non-local variables 3.6.2非局部变量的初始化

The main thing to note is: 要注意的主要事情是:

Non-local variables with static storage duration are initialized as a consequence of program initiation. 具有静态存储持续时间的非局部变量将由于程序启动而初始化。

So in most situations they will all be fully constructed before main is entered. 因此,在大多数情况下,它们都将在输入main之前全部构建完毕。

As noted by others. 正如其他人所指出的。 The compiler is allowed to delay initialization. 允许编译器延迟初始化。

3.6.2 Paragraph 4 3.6.2第4段

It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main. 实现定义是否在第一个main语句之前完成具有静态存储持续时间的非局部变量的动态初始化。

This addition is mainly done to support dynamically loading libraries at runtime (which may by laded dynamically after main has started). 进行此添加主要是为了支持在运行时动态加载库(可以在main启动后动态加载库)。 But it does provide a simple guarantee that all static storage duration objects within a compilation until will be fully constructed before any objects or function in that compilation are used. 但这确实提供了一个简单的保证,即在使用该编译中的任何对象或函数之前,编译中的所有静态存储持续时间对象将被完全构造。

3.6.2 Paragraph 5 3.6.2第5段

If the initialization is deferred to some point in time after the first statement of the initial function of the thread, it shall occur before the first odr-use (3.2) of any variable with thread storage duration defined in the same translation unit as the variable to be initialized. 如果将初始化推迟到线程的初始函数的第一条语句之后的某个时间点,则初始化应发生在任何线程的首次odd使用(3.2)之前,该变量的线程存储持续时间与该变量在同一转换单元中定义进行初始化。

Global variables are initialized at program start-up, before main() is invoked. 全局变量在程序启动时初始化,然后调用main() Static objects that are local to a scope are initialized the first time execution passes over them. 范围本地的静态对象在第一次执行通过它们时被初始化。

Static class members are just global variables, so see above. 静态类成员只是全局变量,因此请参见上文。

Destruction of global and static objects happens after main() returns. main()返回后,将破坏全局对象和静态对象。

(The implementation details of this are fairly intricate, since all the destructors have to be queued up for execution somewhere, and for local statics there needs to be a flag to indicate whether the object has already been instantiated.) (此方法的实现细节相当复杂,因为所有析构函数都必须排队等待在某个地方执行,并且对于局部静态变量,需要有一个标志来指示对象是否已被实例化。)

No, of course, the constructor can't initialize static data members. 不,当然,构造函数无法初始化静态数据成员。 For const integral or enumeration types, you can initialize within the scope of the class definition. 对于const整型或枚举类型,可以在类定义的范围内进行初始化。 However, in general, you must initialize outside the class definition. 但是,通常,您必须在类定义之外进行初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM