【问题标题】:Does make_shared do a default initialization (zero-init) for each member variablemake_shared 是否对每个成员变量进行默认初始化(零初始化)
【发布时间】:2017-07-28 06:27:33
【问题描述】:

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

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&lt;Foo&gt; 的实例并打印:

{
    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++ 的标准吗?或者是否有必要在实例化之后有一个显式的构造函数或显式的={} 语句来保证所有编译器的零初始化行为?

【问题讨论】:

  • 实际问题:您想要一个保证,让您可以依赖这个,还是一个避免它的方法
  • 前者。我想确保它是标准行为,以便可以在不同的编译器中依赖它。

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


【解决方案1】:

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

该对象是由表达式::new (pv) T(std::forward&lt;Args&gt;(args)...) 构造的,其中pv 是一个内部void* 指针,指向适合保存T 类型对象的存储空间。

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

【讨论】:

    【解决方案2】:

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

    对象是由表达式::new (pv) T(std::forward&lt;Args&gt;(args)...)构造的

    对于具有空初始化列表的Foo,这意味着其所有具有内置类型的成员将是zero-initialized,而std::string 将是default-initialized

    【讨论】:

      猜你喜欢
      • 2015-03-22
      • 2014-12-29
      • 1970-01-01
      • 1970-01-01
      • 2013-10-14
      • 2015-10-09
      • 2021-11-11
      • 2016-02-01
      • 2019-09-10
      相关资源
      最近更新 更多