对于以下代码段:
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] 删除。
我来说两句