简体   繁体   English

静态数据成员是否在所有类对象之前初始化?

[英]Are static data members initialized before all class objects?

For example: 例如:

#include<iostream>
using namespace std;
class A
{
    public:
    A(){cout<<k<<endl;}//make some output
    static int k;
};
A a;//before `k`'s definition
int A::k=666;
int main()
{

}

Is the answer guaranteed to be 666 (I've tested it in gcc8.1.0 the answer is 666 ) or causing undefined behavior? 答案保证是666 (我已经在gcc8.1.0中测试了答案是666 )或导致未定义的行为?

What's more, in this example, object a and definition A::k are in the same translation unit, what will happen if they are in different units, since 更重要的是,在这个例子中,对象a和定义A::k在同一个翻译单元中,如果它们在不同的单元中会发生什么,因为

Initialization of static variables in different translation units is indeterminately sequenced 不同翻译单元中的静态变量的初始化是不确定的

From my point of view, since in the same TU the initializaition order is fixed, the answer of the example above should be undfined. 从我的观点来看,由于在相同的TU中初始化顺序是固定的,因此上述示例的答案应该是未定义的。

If you were to make the constructor a non-inline function, yes, it would be guaranteed to be the value you expect. 如果你要使构造函数成为非内联函数,是的,它将保证是你期望的值。

k will be subject to constant initialization (on account of the constant initializer), while a 's initialization is dynamic. k将受到恒定初始化 (在帐户中的常量初始化的),而a的初始化是动态的。 All static initialization happens before dynamic initialization of static objects. 所有静态初始化都在静态对象动态初始化之前发生 But even if k was initialized dynamically: 但即使k 动态初始化的:

[basic.start.dynamic] (emphasis mine) [basic.start.dynamic] (强调我的)

4 It is implementation-defined whether the dynamic initialization of a non-local non-inline variable with static storage duration is sequenced before the first statement of main or is deferred. 4实现定义了具有静态存储持续时间的非本地非内联变量的动态初始化是在主要的第一个语句之前还是在延迟之后排序。 If it is deferred, it strongly happens before any non-initialization odr-use of any non-inline function or non-inline variable defined in the same translation unit as the variable to be initialized . 如果它是延迟的,则在任何非初始化odr使用任何非内联函数或非内联变量之前强烈发生,该非内联函数或非内联变量在与要初始化的变量相同的转换单元中定义 It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs. 它是实现定义的,其中线程和程序中的哪些点发生延迟动态初始化。

And a non-inline constructor qualifies for such a function. 非内联构造函数有资格使用这样的函数。 This is the basis for the Schwarz Counter technique. 这是Schwarz Counter技术的基础。

But in your example, the c'tor is an inline function. 但在你的例子中,c'tor是一个内联函数。 So it's only due to constant initialization that you get 666. Should the initializer not be a constant expression, a would be undergo dynamic initialization before k according to declaration order in the same TU. 所以这只是由于你得到的常量初始化666.如果初始化器不是常量表达式,则根据同一TU中的声明顺序, a将在k之前进行动态初始化。

Are static data members initialized before all class objects? 静态数据成员是否在所有类对象之前初始化?

Depends. 要看。 All objects with static storage duration, which includes all static data members, are initialised before main . 具有静态存储持续时间的所有对象(包括所有静态数据成员)在main之前初始化。 But if you have class objects with static storage duration, then those class objects may be initialised before static data members. 但是如果你有具有静态存储持续时间的类对象,那么这些类对象可以在静态数据成员之前初始化。

Is the answer guaranteed to be 666 答案保证是666

Yes. 是。

causing undefined behavior? 导致未定义的行为?

No UB here. 没有UB在这里。

what will happen if they are in different units 如果他们在不同的单位会发生什么

Initialisation of the static member is constant, while the constructor of a is called during the dynamic initialisation of static objects. 静态成员的初始化是常量,而在静态对象的动态初始化期间调用a的构造函数。 Constant initialisation phase is before dynamic phase. 恒定初始化阶段在动态阶段之前。 Thus it doesn't matter in this case whether they are declared in different TU's. 因此,在这种情况下,它们是否在不同的TU中声明并不重要。

Static member is given a separate room. Static会员有一个单独的房间。 Whether you initialize it before object creation of the class or not, will not have any effect. 无论是否在创建类的对象之前初始化它都不会产生任何影响。 The program will run without undefined behavior. 该程序将运行没有undefined行为。

For example In C#, the if the static member's value is not set, it is given 0 value by the compiler. 例如,在C#中,如果未设置static成员的值,则编译器将给出0值。

  • You can get/set value of static member after the object creation of the class 在创建类的对象之后,您可以获取/设置static成员的值
  • You can set before as well, as you know already. 如您所知,您也可以在之前设置。

After setting it as 666 , other objects made of that class A will get it value as 666 将其设置为666 ,由该类A组成的其他对象将其值设为666

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

相关问题 如何初始化属于类的成员并且与它们所在的类具有相同类型的静态对象? - How are static objects, that are members of a class and that are of the same type as the class they are in, initialized? 静态类成员是否保证在调用`main`之前初始化? - Are static class members guaranteed to be initialized before `main` is called? 为什么所有对象的类的静态成员都相同? - Why are the static members of a class the same for all objects? 静态数据成员值是否已初始化? - Are static data members value initialized? 只能在类中初始化静态const整数数据成员 - Only static const integral data members can be initialized within a class C ++中的静态对象是类的静态数据成员还是静态方法? - Are the static data members and static methods of a class in C++ static objects? 静态C ++类成员何时初始化? - When are static C++ class members initialized? 全局对象和类的静态成员 - Global objects and static members of class C ++类的Qt类数据成员是否应该在使用之前进行初始化? - Should Qt class data members of a C++ class be initialized before being used? 为什么在类中初始化的非整数静态数据成员必须是constexpr? - Why must non-integral static data members initialized in the class be constexpr?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM