在c ++ 11中,你可以这样做:
class Foo
{
public:
Foo();
bool test = false;
};
Foo::Foo()
{
// is test guaranteed to be false now? and is it surely not overriden later?
this->test = true;
}
我想知道的内容基本上是在评论中描述的,我可以用我的编译器来验证这一点,但这是在标准中提到的吗?它在所有平台和所有编译器上是否总是相同的?
答案 0 :(得分:2)
现在测试保证是假的吗?是。
以后肯定不会覆盖吗?它不会被覆盖。默认值设置为构造函数开头的初始化列表的一部分。
如果初始化列表中没有包含test,则编译器会将其置于默认值中。对于构造函数,编译器实际上会为此生成代码:
Foo::Foo()
: test(false)
{
// is test guaranteed to be false now?
this->test = true;
// is it surely not overriden later?
}
使用此构造函数测试将首先初始化为false,然后在body中设置为true。
如果你写了:
Foo::Foo()
: test(true)
{
}
测试将在初始化列表中,并且编译器不会将其放在那里,测试将直接初始化为true。
答案 1 :(得分:2)
在C ++ 11中,有三个地方可以初始化非静态数据成员:
如果非静态数据成员同时具有大括号或等于初始化和 mem-initializer ,那么 mem-initializer 覆盖 brace-or-equal-initializer ;这在12.6.2.p9中指定。
在任何一种情况下,非静态数据成员的初始化都在输入构造函数体之前发生,因此构造函数可以改变成员的值。
答案 2 :(得分:2)
来自[ class.base.init ] 12.6.2 - 初始化基础和成员
9 如果给定的非静态数据成员同时具有大括号或等于初始化程序, mem-initializer ,执行mem-initializer指定的初始化, 并忽略非静态数据成员的 brace-or-equal-initializer 。
实施例
struct A
{
int i = /∗ some integer expression with side effects ∗/ ;
A(int arg) : i(arg) { } // ...
};
A(int)
构造函数只会将i
初始化为arg
的值,并且i
中的副作用会支持 - 或 - <_p>将不会发生等于初始化。
10 在非委托构造函数中,初始化在以下进行 顺序:
- 首先,仅适用于派生程度最高的类(1.8)的构造函数, 虚拟基类按它们在深度优先上显示的顺序进行初始化 从左到右遍历基类的有向无环图,其中 “从左到右”是派生类中基类出现的顺序 基符列表
- 然后,直接基类按声明顺序初始化 出现在 base-specifier-list 中(无论顺序如何 MEM-初始化)。
- 然后,按照声明的顺序初始化非静态数据成员 类定义(再次与 mem-initializers 的顺序无关)。
- 最后,执行构造函数体的复合语句。
所以
class Foo
{
public:
Foo();
bool test = false;
};
Foo::Foo()
{
// is test guaranteed to be false now? and is it surely not overriden later?
this->test = true;
}
test
保证为false
并且不会被覆盖(&#34;最后,构造函数体的复合语句被执行&#34; < / em>的)