C++:关于初始化语法、值初始化和默认初始化的3个问题
C++ : 3 questions about initialization syntax, value-initialization and default-initialization
所以我非常努力地理解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"。
谢谢。
-
int x(1);
与为内置类型写入int x = 1;
相同。 -
对于具有用户定义构造函数(非聚合)的类型,编写
T()
总是调用默认构造函数;这就是代码不能编译的原因。 -
c1.i
实际上是未初始化的,读取它是未定义的行为。您的编译器可能正在将内存归零,尤其是在没有打开优化的情况下;或者只是碰巧打印出零。你当然不能指望这种行为。这是clang打印垃圾的输出。
-
符号
int x(1);
称为直接初始化。它是为本机类型和类分别定义的。在后一种情况下,将调用构造函数。 -
在这种情况下,如果没有默认构造函数,就不存在值初始化。构造临时对象的规则与构造命名对象的规则相同。
-
读取未初始化的值会产生未定义的行为。再次运行相同的程序可能总是会产生相同的结果,但尝试其他程序、其他机器、其他平台可能会(也可能不会)发生其他事情。Undefine字面意思是未定义的标准,不是崩溃或随机或产生错误消息。
对于那些只依赖包括所有聪明人在内的最佳可用规范的保证的人来说,具有未定义行为的程序是不正确的,可以假设它在你最意想不到的时候崩溃了。
如果在调试模式下运行程序,它会显示:
c1.i=-885993460
是"CCCCC…CC"的值,这是C++调试模式下未初始化值的默认值。
- 初始化具有非默认构造函数的std::数组项的更好方法
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 副本初始化的默认模板参数推导
- 使用 std::分配器在 constexpr 中进行默认初始化
- 在C++中使用默认构造函数初始化对象的不同方法
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数时使用垃圾数据初始化对象
- 为什么对象默认初始化,但基元不在C++?
- 默认参数和空列表初始化
- 为什么std::atomic的默认构造函数不默认初始化底层存储值
- C++中未初始化成员布尔变量的默认值是多少?
- 两个成员,在Base中默认初始化,可能在Derived中非默认初始化
- 默认初始化无法正常工作
- 如何用默认值0或-1初始化unordered_set
- C++11 默认类成员初始化与初始值设定项列表同时
- 使用聚合初始化模拟默认函数参数是否存在任何陷阱?
- 初始化在类类型 #define 中定义的非静态成员数组,不带默认 ctor
- 在皮条类中初始化默认值的最佳位置
- 值初始化:默认初始化或零初始化