make_shared是否为每个成员变量执行默认初始化(zero-init)

sel*_*bie 11 c++ initialization shared-ptr c++11

将普通的旧数据类型和对象作为成员的普通结构(或类).请注意,没有定义默认构造函数.

struct Foo
{
    int x;
    int y;
    double z;
    string str;
};
Run Code Online (Sandbox Code Playgroud)

现在,如果我在堆栈上声明一个实例f并尝试打印其内容:

{
    Foo f;
    std::cout << f.x << " " << f.y << " " << f.z << f.str << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

结果是为x,y和z打印的垃圾数据.并且字符串默认初始化为空. 正如所料.

如果我创建一个shared_ptr<Foo>使用make_shared和打印的实例:

{
    shared_ptr<Foo> spFoo = make_shared<Foo>();
    cout << spFoo->x << " " << spFoo->y << " " << spFoo->z << spFoo->str << endl;
}
Run Code Online (Sandbox Code Playgroud)

然后,x,y和z都是0.这使得它似乎shared_ptr在构造对象实例后对每个成员执行默认初始化(零init).至少这是我用Visual Studio的编译器观察到的.

这是C++的标准吗?或者是否有必要={}在实例化后使用显式构造函数或显式语句来保证所有编译器的零init行为?

Som*_*ude 11

如果你看到这个std::make_shared参考,你会看到

该对象就像表达式一样构造::new (pv) T(std::forward<Args>(args)...),其中pv是一个内部void*指针,指向适合容纳类型对象的存储T.

这意味着std::make_shared<Foo>()基本上new Foo().也就是说,它的值初始化导致非类成员变量归零的结构.


son*_*yao 6

更精确地说,性病:: make_shared聘用过的员工值初始化语法,

该对象就像表达式一样构造 ::new (pv) T(std::forward<Args>(args)...)

对于Foo空的初始化列表,这意味着所有具有内置类型的成员都将进行零初始化,std::string并将进行默认初始化.