所以我真的很难理解C ++中的初始化规则。
我写了以下代码:
struct B {
int i;
// this prevents the definition of an implicit default constructor
B( int j ) : i(j) {}
};
struct C {
int i;
// i is not mentioned in the initializer list
// the compiler will call default constructor for i
C() {}
};
int main() {
int x( 1 );
cout << " x = " << x << endl;
// error: no matching function for call to ‘B::B()’
//B b4 = B();
//cout << " b4.i = " << b4.i << endl;
C c1;
cout << " c1.i = " << c1.i << endl;
}
1)x被正确初始化为1,但我不理解符号“int x(1)”。 它不是值初始化的(我们会写“int x = int()”,然后x将是0)。 它也不是构造函数调用,因为内置类型没有构造函数。 此外,以下页面清楚地表明:“只能使用函数式语法初始化具有构造函数的类的对象”。
http://msdn.microsoft.com/en-us/library/w7wd1177(v=vs.100).aspx
2)如果我取消注释b4的创建,它将无法编译。因为我定义了一个构造函数,所以编译器不会生成隐式的默认构造函数。这可以。但是为什么这会阻止使用“B()”创建临时的值初始化对象?写“B()”永远不是构造函数调用,是吗?
3)如C类评论中所述,初始化列表中未提及i。因此,它应该是默认初始化的,这意味着int类型未定义。但是每次运行程序时输出都是“c1.i = 0”。
感谢。
答案 0 :(得分:3)
int x(1);
与为内置类型编写int x = 1;
相同。
对于具有用户定义构造函数的类型(非aggregate),编写T()
总是调用默认构造函数;这就是代码无法编译的原因。
c1.i
确实未初始化,阅读它是未定义的行为。您的编译器可能正在将内存归零,特别是如果您没有启用优化;或者恰好打印出零的机会。你当然不能指望这种行为。这是output from clang印刷垃圾。
答案 1 :(得分:2)
符号int x(1);
称为直接初始化。它是针对本机类型和类别单独定义的。在后一种情况下,将调用构造函数。
在这种情况下,如果没有默认构造函数,则不会进行值初始化。构造临时的规则与构造命名对象的规则相同。
读取未初始化的值会产生未定义的行为。再次运行相同的程序可能总是产生相同的结果,但尝试其他程序,其他机器,其他平台,可能(或可能不)使其他事情发生。未定义的字面意思是标准未定义,不会崩溃或随机或产生错误消息。
对于那些仅依赖于最佳可用规范(包括所有智能人员)的保证的人来说,具有未定义行为的程序是不正确的,可以假设在您最不期望的时候崩溃
答案 2 :(得分:0)
如果在调试模式下运行程序,它会显示:
c1.i = -858993460
这是“CCCCC ... CC”的值,这是C ++调试模式中未初始化值的默认值。