make_shared 是否对每个成员变量进行默认初始化(零初始化)?

13

拿一个普通的结构体(或类),其中成员都是普通数据类型和对象。注意,没有定义默认构造函数。

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,打印出的数据是垃圾数据。字符串被默认初始化为空。 如预期所示。

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

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

那么,x、y和z都是0。这似乎表明,在对象实例构造之后,shared_ptr执行了默认初始化(零初始化)于每个成员上。至少这是我用Visual Studio编译器观察到的。

对于C ++来说,这是标准的吗?还是必须在实例化后具有显式构造函数或显式 = {} 语句才能保证在所有编译器中实现零初始化行为?


实际问题:您是想要一个可以依赖的保证,还是一种避免它的方法? - Yakk - Adam Nevraumont
前者。我想确保它是标准行为,以便可以在不同的编译器中依赖它。 - selbie
2个回答

14
如果您看到例如 this std::make_shared reference,您将会看到
该对象的构造方式类似于表达式::new (pv) T(std::forward<Args>(args)...),其中pv是一个指向内部适合容纳类型为T的对象的void*指针。
这意味着std::make_shared<Foo>()基本上执行了new Foo()。也就是说,它值初始化了结构体,从而导致非类成员变量的清零。

8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接