c – 构造函数执行顺序/顺序:函数中静态变量(类实例)的依赖初始化

对于以下代码段:

class Bar {
public:
    int x;
    int y;
    Bar(int _x, int _y) {  /* some codes here */ ...}
};
class Foo {
public:
    int x;
    int y;
    int z;
    Foo(Bar b):x(b.x), y(b.y)
    {
        z = someFunction(x, y);
    }
};

void f(int x, int y)
{
     Bar b(x, y);
     static Foo x(b);
}
int main()
{
     f(2, 3);
}

在我看来,函数内部的静态变量应该在main()之前初始化.但是,Foo类型的静态变量x取决于Bar类型的局部变量b.

问题是:

1)x的构造函数何时执行?即,第一次调用局部变量b初始化x?我不想要一些特殊编译器案例的特定结果,但想知道它是否在C语言中定义良好.

2)这是一个有效的计划吗?

3)这是一个好习惯吗?

最佳答案

In my mind, a static variable inside a function should be initialized even before main()

你的思想是错误的……至少部分是这样.静态局部变量可以在某些情况下尽早初始化,但不能在构造函数依赖于本地变量(例如此变量)的情况下初始化.

n3242标准草案§6.7/ 4:

… An implementation is permitted to perform early initialization of other block-scope variables with static or thread storage duration under the same conditions that an implementation is permitted to statically initialize a variable with static or thread storage duration in namespace scope (3.6.2). Otherwise such a variable is initialized the first time control passes through its declaration; …

为了完整性,以下是常量(静态)初始化§3.6.2/ 2的要求:

Constant initialization is performed:

— if each full-expression (including implicit conversions) that appears in the initializer of a reference with
static or thread storage duration is a constant expression (5.19) and the reference is bound to an lvalue
designating an object with static storage duration or to a temporary (see 12.2);

— if an object with static or thread storage duration is initialized by a constructor call, if the constructor is
a constexpr constructor, if all constructor arguments are constant expressions (including conversions),
and if, after function invocation substitution (7.1.5), every constructor call and full-expression in the
mem-initializers is a constant expression;

— if an object with static or thread storage duration is not initialized by a constructor call and if every
full-expression that appears in its initializer is a constant expression.

1)当第一次执行到达它的声明时,x被初始化,并且当构造函数运行时.因此,当x的初始化开始时,b被完全初始化.

2)就初始化依赖性而言,是的.

3)当然,如果需要,静态本地对象的构造函数可能依赖于本地对象.只要在超出范围之后不引用该本地对象.在这种情况下,您只需复制它的成员,因此在构造x之后您不依赖它.

转载注明原文:c – 构造函数执行顺序/顺序:函数中静态变量(类实例)的依赖初始化 - 代码日志