【问题标题】:Should I use smart pointers here?我应该在这里使用智能指针吗?
【发布时间】:2017-09-20 00:20:10
【问题描述】:

我已经阅读了几个关于类似问题的答案,但我仍然对何时是使用智能指针的好时机感到困惑。我有一个类Foo,看起来像这样:

class Bar;
class Baz;

class Foo
{
public:
    Foo(Bar* param1, std::vector<Baz*>& param2);

    virtual ~Foo();

    // Method using myBar and myBaz polymorphically...

private:
    Bar*               myBar;
    std::vector<Baz*>  myBaz;
};

我需要两个数据成员作为多态的指针。是一部分 一个API,我担心有人写:

int main()
{
    //...

    std::vector<Baz*> allOnHeap {new Baz(), new Baz()};

    Foo(new Bar(), allOnHeap);

    // ...
}

这是合法的,但会导致内存泄漏。我可以添加deletes 析构函数,但是如果没有动态分配怎么办 制作?在您看来,使用 smart 是个好主意吗? 在这种情况下指针?请说明你的意见。如果您对如何执行此操作有更好的想法,请随时分享。

【问题讨论】:

  • 智能指针都是关于所有权的。这个问题归结为您是否希望Foo 拥有它指向的对象。如果不是,那么您的代码很好,Foo 的用户需要管理对象的生命周期。如果他们泄漏,就这样吧,不是Foo 的错。但是,如果您希望Foo 拥有所有权,则将myBar 更改为std::unique_ptr&lt;Bar&gt;std::shared_ptr&lt;Bar&gt;,并将myBaz 更改为std::vector&lt;std::unique_ptr&lt;Baz&gt;&gt;std::vector&lt;std::shared_ptr&lt;Baz&gt;&gt;。那么就不会再有谁拥有什么的问题了。
  • 是的,这是std::unique_ptrs 有用的标准情况之一。
  • @RemyLebeau 在哪种情况下我可以不关心我的课程可能会产生内存泄漏的事实?在我看来,原始指针数据成员总是会导致这种问题。我错了吗?
  • @BobMorane 再次,这是所有权问题。 Foo 不分配对象。如果它不获取所给对象的所有权,则它没有使用指向它们的智能指针的业务(或者,至少它可以通过std::shared_ptr 使用共享所有权)。您已经说明了需要原始指针的上下文 - “没有进行动态分配
  • 旁注:Foo() = delete; 在这里是多余的。

标签: c++11 smart-pointers


【解决方案1】:

我已经阅读了几个关于类似问题的答案,但我仍然 对于何时是使用智能指针的好时机感到困惑。我有一个 Foo 类看起来像这样:

在你提到的情况下,我会使用智能指针。

  1. 目前复制您的课程并不安全
  2. 您无法知道您在列表中引用的对象在引用时是否仍然存在
  3. RAII 不会自动用于 我的酒吧

更具体地说,恕我直言,您可以为您需要的所有权语义建模:

使用unique_ptr&lt;Bar&gt;std::vector&lt;weak_ptr&lt;Baz&gt;&gt;

  • unique_ptr&lt;Bar&gt; 在持有类作用域结束时自动清理

  • std::vector&lt;weak_ptr&lt;Baz&gt;&gt;:每个weak_ptr 都表明使用类(将通过weak_ptr 访问的类)没有所有权语义,并且在使用之前必须尝试获得临时所有权(通过锁定这给一个一个 shared_ptr)。

使用上面提到的智能指针,当你错误地复制开箱时你会得到一个编译器错误(因为 unique_ptr 是不可复制的),更重要的是,列表中的每个项目都可以安全地访问。持有类的实例化器也对类编写者设想的所有权语义有一个清晰的想法

顺便说一句,您不必显式删除默认构造函数。 See了解详情。

【讨论】:

    【解决方案2】:

    在这种情况下,智能指针不会立即跳入脑海,主要是因为不清楚所有权要求是什么。如果您遵循关于 ownership transfer and raw pointers 的 C++ 核心指南建议,那么很明显,class Foo 并不打算拥有 BarBaz 对象,并且不应删除它们。

    如果您的意图是有时可能拥有对象的所有权,有时不拥有所有权,我建议您考虑一种替代设计,您可以选择一个单一的功能并坚持使用它(:

    【讨论】:

    • 也许智能指针应该总是跳到脑海来定义所有权语义应该是什么。
    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 2013-06-27
    • 2014-03-11
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    相关资源
    最近更新 更多