为什么在同一个类上使用不同的(shared_ptr和normal)指针构造函数我会得到不同的结果?

时间:2015-05-11 22:41:13

标签: c++ c++11 constructor initialization default

this question的启发,我编写了自己的小程序(使用this answer中的代码)并发现了让我困惑的事情。即:

有这些课程:

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

虽然aforementioned question's answers //2 //3//4predict.lm中发生了什么,但第一个问题是如何描述的?

我在Ubuntu 64位上使用了gcc 4.9.2和5.1.0,结果相同。

Ideone link

2 个答案:

答案 0 :(得分:5)

您的前三个代码段 value-initialize 构造的对象。

如果类的默认构造函数不是用户提供的,则value-initialization执行零初始化,然后调用默认构造函数;否则,它只调用默认构造函数。

现在在链接的问题中应用讨论。

对于window.socket.emit('embed',{'...'}); 在两种情况下都看到全零的情况,这只是未定义行为的一种可能表现形式。没什么。

最终片段默认初始化构造的对象,对于类类型的对象,这意味着调用默认构造函数,在每种情况下都不执行初始化。

答案 1 :(得分:0)

你永远不会初始化i和j。然后行为未定义 - 随机。