为什么在同一类中使用不同的(共享_ptr和正常)指针构造函数,我会得到不同的结果



受这个问题的启发,我写了自己的小程序(使用此答案中的代码),发现了使我感到困惑的事情。即:

有这些类:

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。然后,行为不确定 - 随机。

最新更新