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

徐若

对于以下代码段:

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()然而,静态变量x类型Foo取决于局部变量b类型Bar

问题是:

1)什么时候x执行构造函数即是否x在首次调用局部变量时进行了初始化b我不希望某些特殊编译器情况的某些特定结果,但想知道它是否在C ++语言中定义良好。

2)它是有效程序吗?

3)这是一个好习惯吗?

埃雷里卡

在我看来,函数内部的静态变量甚至应在main()之前初始化

您的想法是错误的……至少部分是错误的。静态局部变量在某些情况下可能会提前初始化,但在构造函数依赖于此类局部变量的情况下则不会初始化。

标准§6.7/ 4的n3242草案:

...允许实现在名称空间范围内以静态或线程存储持续时间静态初始化变量的相同条件下对其他具有静态或线程存储持续时间的块作用域变量进行早期初始化(3.6.2 )。否则,该变量将在控件第一次通过其声明时进行初始化;...

为了完整起见,这是常量(静态)初始化§3.6.2/ 2的要求:

执行常量初始化:

—如果出现在具有静态或线程存储持续时间的引用的初始化程序中出现的每个完整表达式(包括隐式转换)是一个常量表达式(5.19),并且该引用绑定到一个指定具有静态存储持续时间的对象的左值或临时的(见12.2);

—如果具有静态或线程存储持续时间的对象通过构造函数调用初始化,如果构造函数是constexpr构造函数,如果所有构造函数参数都是常量表达式(包括转换),并且在函数调用替换之后(7.1.5), mem初始化程序中的每个构造函数调用和完整表达式都是一个常量表达式;

—如果具有静态或线程存储持续时间的对象未通过构造函数调用初始化,并且其初始化程序中出现的每个完整表达式都是常量表达式。

1)x在执行第一次到达其声明时(即构造函数运行时进行初始化。因此,b初始化x开始时已完全初始化

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在具有私有构造函数的类中初始化静态变量

类静态变量的初始化顺序

构造函数是否需要初始化静态变量?

在静态构造函数中初始化静态变量而不是直接赋值的好处是什么?

DI、构造函数、字段初始化执行顺序

模板函数中的C ++静态变量初始化

同一个函数中的静态函数变量初始化顺序

类C ++的静态函数成员中的静态数据成员的初始化顺序

函数调用的静态初始化顺序

Dart构造函数初始化顺序

静态变量初始化的顺序,Java

C ++静态变量初始化顺序

类内初始化与构造函数初始化列表的顺序

PHP-在类的构造函数中初始化对象的实例,在静态成员中进行访问

显式实例化模板的静态成员和另一个静态变量的初始化顺序

静态和非静态成员数据的初始化和构造函数的顺序

在构造函数中初始化空实例变量

在构造函数中初始化静态变量时,为什么Java不给出错误?

我们可以在构造函数内部初始化静态变量吗?

Java构造函数中类变量的初始化

在类的构造函数中初始化ifstream变量

在构造函数中初始化类成员变量

在没有构造函数的类中初始化变量

用函数的参数初始化静态变量

C函数内部的静态变量初始化

为什么我们不能在构造函数初始化列表中初始化静态变量,但可以在构造函数主体中初始化

构造函数初始化列表评估顺序

C ++:构造函数按初始化列表的顺序

在类本身中初始化 TypeScript 变量与在构造函数中初始化的区别