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

时间:2017-07-28 06:27:34

标签: c++ c++11 initialization shared-ptr

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

struct Foo
{
    int x;
    int y;
    double z;
    string str;
};

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

{
    Foo f;
    std::cout << f.x << " " << f.y << " " << f.z << f.str << std::endl;
}

结果是为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;
}

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

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

2 个答案:

答案 0 :(得分:10)

如果您看到例如this std::make_shared reference你会看到

  

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

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

答案 1 :(得分:6)

更准确地说,std::make_shared使用value initialization语法,

  

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

一样

对于包含空初始值设定项列表的Foo,这意味着其内置类型的所有成员都为zero-initialized,而std::string将为default-initialized