为什么在同一个 class 上使用不同的(shared_ptr 和普通的)指针构造函数会得到不同的结果?
Why using different (shared_ptr and normal) pointer constructors on the same class I get different results?
受到 this question I wrote my own little program (using code from 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
、//4
中发生了什么?
我在 Ubuntu 64 位上使用 gcc 4.9.2 和 5.1.0,结果相同。
你永远不会初始化 i 和 j。行为是未定义的 - 随机的。
你的前三个代码片段value-initialize构造的对象。
如果class的默认构造函数不是用户提供的,值初始化执行零初始化,然后调用默认构造函数;否则,它只调用默认构造函数。
现在应用链接问题中的讨论。
对于 make_shared
情况,您在两种情况下都看到全零,这只是未定义行为的一种可能表现形式。仅此而已。
最后一段 default-initializes 构造的对象,对于 class 类型的对象,这意味着调用默认构造函数,在每种情况下都不执行初始化.
受到 this question I wrote my own little program (using code from 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
、//4
中发生了什么?
我在 Ubuntu 64 位上使用 gcc 4.9.2 和 5.1.0,结果相同。
你永远不会初始化 i 和 j。行为是未定义的 - 随机的。
你的前三个代码片段value-initialize构造的对象。
如果class的默认构造函数不是用户提供的,值初始化执行零初始化,然后调用默认构造函数;否则,它只调用默认构造函数。
现在应用链接问题中的讨论。
对于 make_shared
情况,您在两种情况下都看到全零,这只是未定义行为的一种可能表现形式。仅此而已。
最后一段 default-initializes 构造的对象,对于 class 类型的对象,这意味着调用默认构造函数,在每种情况下都不执行初始化.