将std :: shared_ptr传递给构造函数

Baz*_*Baz 8 c++ std

以下是关于创建Stuff和赋予它Foo所有权的合理有效的方法吗?

class Foo
{
    explicit Foo(const std::shared_ptr<Stuff>& myStuff)
        : m_myStuff(myStuff)
    {
    }

    ...

private:
    const std::shared_ptr<Stuff> m_myStuff;
}

std::shared_ptr<Stuff> foosStuff(new Stuff());
Foo f(foosStuff);
Run Code Online (Sandbox Code Playgroud)

sel*_*tze 23

既然你对效率感兴趣,我想提出两点:

shared_ptr <>是许多标准库类型之一,其中移动构造比复制构造便宜.复制构造shared_ptr较慢,因为复制需要引用计数器以原子方式递增,而移动shared_ptr则根本不需要触摸引用的数据或计数器.从Dave Abrahams 的文章" 想要速度?通过价值! "中可以了解到,在某些情况下,按值获取函数参数实际上是有益的.这是以下情况之一:

class Foo
{
  explicit Foo(std::shared_ptr<Stuff> myStuff)
  : m_myStuff(move(myStuff))
  {}

  ...

private:
  std::shared_ptr<Stuff> m_myStuff;
};
Run Code Online (Sandbox Code Playgroud)

现在你可以写了

Foo f (std::make_shared<Stuff>());
Run Code Online (Sandbox Code Playgroud)

其中参数是临时的,并且没有复制shared_ptr(只移动一次或两次).

在这里使用std :: make_shared的优点是只进行了一次分配.在您的情况下,您自己分配了Stuff对象,而shared_ptr构造函数也必须动态分配引用计数器和删除器.make_shared只需一次分配即可完成所有操作.

  • 我喜欢那个 make_shared 函数 (2认同)

jle*_*ahy 5

是的,这是完全合理的。这样,管理共享指针所涉及的工作只需执行一次,如果按值传递则不需要执行两次。您还可以考虑使用 make_shared 来避免复制构造。

std::shared_ptr<Stuff> foosStuff(std::make_shared<Stuff>());
Run Code Online (Sandbox Code Playgroud)

您可以做出的唯一改进是,如果 Foo 是唯一所有者(即,在创建 Foo 后您不会保留 foosStuff),那么您可以切换到使用 std::unique_ptr 或 boost::scoped_ptr(这是C++11 之前的等效项),这将减少开销。

  • @KerrekSB 我也想,但假设并不能帮助任何阅读答案的人理解在 C++ 标准库中有一个非常合适的所有权获取指针,而无需使用 boost(甚至没有提到)。问题已经改变了。一旦他注意到问题的变化和不准确的信息,对他的回答的反对票就会神奇地消失。 (2认同)