受这个问题的启发,我写了自己的小程序(使用此答案中的代码),发现了使我感到困惑的事情。即:
有这些类:
class A {
public:
A(){}
int i;
int j;
};
class B {
public:
B() = default;
int i;
int j;
};
我写了4种具有不同对象构造使用情况的类的用法:
//1
A* pa = new A(); // followed by delete pa
B* pb = new B(); // followed by delete pb
//2
shared_ptr<A> pa = make_shared<A>();
shared_ptr<B> pb = make_shared<B>();
//3
shared_ptr<A> pa ( new A() );
shared_ptr<B> pb ( new B() );
//4
shared_ptr<A> pa ( new A );
shared_ptr<B> pb ( new B );
之后,我用它们来打印它们的价值:
for( int i = 0; i < 3; ++i)
{
...1..2..3..4
cout << "A : " << pa->i << "," << pa->j << endl;
cout << "B : " << pb->i << "," << pb->j << endl;
}
我在输出上收到的内容使我感到惊讶:
//1
A : 0,0
B : 0,0
A : 7388176,0
B : 0,0
A : 7388208,0
B : 0,0
//2
A : 0,0
B : 0,0
A : 0,0
B : 0,0
A : 0,0
B : 0,0
//3
A : 0,0
B : 0,0
A : 25848848,0
B : 0,0
A : 25848880,0
B : 0,0
//4
A : 0,0
B : 0,0
A : 39619600,0
B : 39619664,0
A : 39619632,0
B : 39619696,0
虽然上述问题的答案中的第一个描述了第一个, //2
, //3
, //4
?
我在Ubuntu 64位上使用GCC 4.9.2和5.1.0,结果相同。
IDEONE链接
您的前三个代码段 value-initialize 构建的对象。
如果同类的默认构造函数不是用户提供的,则值initialization执行零定位化,然后调用默认构造函数;否则,它只是调用默认构造函数。
现在在链接的问题中应用讨论。
对于make_shared
的情况,您在两种情况下都会看到所有零,这只是不确定行为的一种可能表现。仅此而已。
最终片段 default-initialize 构建的对象,对于类型的对象,它是指调用默认构造函数,在每种情况下都不执行初始化。
您永远不会初始化i和j。然后,行为不确定 - 随机。