【问题标题】:Optional pointer ownership可选的指针所有权
【发布时间】:2020-07-28 06:15:42
【问题描述】:

让我们考虑这个类,它拥有或查看一个指针,具体取决于它的构造方式。

template<class T>
class OptionalUniquePtr
{
  public:

    OptionalUniquePtr(p*)
    : m_p(p)
    {}

    OptionalUniquePtr(std::unique_ptr<T>&& p)
    : m_owned_p(std::move(p))
    , m_p(p)
    {}

    T* get()
    {
      return m_p;
    }

 private:

   std::unique_ptr<T> m_owned_p;
   T *m_p;
};

除了调整或优化之外,我的问题是:这是一个坏主意吗? 我正在编写一些可以选择拥有或查看一些指针的代码:

std::unique_ptr<Bar> b1 = ...;
Bar *b2 = ...;
// one million lines later
Foo f1(std::move(b1),...); // ownership transfered to f1
Foo f2(b2,...); // just viewing b2, caller manages lifetime. Risky, but usually owners have long lifetime

想象一下,Foo 是一个大类,它在 Bar 上做一些事情。 我希望 Foo 能够灵活地接受两者,所以它里面可以有一个 OptionalUniquePtr 。另一种方法是像这样模板化 Foo

Foo<std::unique_ptr<Bar>> f1(std::move(b1),...);
Foo<Bar*> f1(b2,...);

第二种方法的优点是更明确的内存所有权。

另一种选择是使用 std::shared_ptr 开始,但在庞大的代码库中这是不可行的。

社区对 OptionalUniquePtr 有何看法?

谢谢

西蒙娜

【问题讨论】:

  • 我真的不明白这个东西的用例可能是什么。在您的上一个示例中,Foo 有什么意义?与所有权的唯一指针和非所有权的原始指针相比,这是一种额外的间接寻址。
  • @Mat Foo 是一个使用 Bar 的大类。成像其构造函数还有其他 4 个参数。根据具体情况,我希望它拥有或只是查看一个 Bar。 Foo 的不同构造函数将触发一种或另一种行为。我编辑了帖子以更清楚地了解 Foo 的角色。
  • 考虑使用std::shared_ptr,它已经做了可选的所有权。
  • 怎么样?我看到 shared_ptr 可以收到一个 unique_ptr (转让所有权),但我如何处理非所有权情况?我无法更改原始代码以使用 shared_ptr 开始。
  • 我想我找到了答案:对于非所有权使用 shared_ptr 别名构造函数。

标签: c++ c++11 pointers memory-management unique-ptr


【解决方案1】:

答案是std::shared_ptr已经实现了这种“可选所有权”。代码如下所示:

std::unique_ptr<Bar> bar1 = ...;
Bar* bar2 = ...;

Foo f1(std::move(bar1));
Foo f2(bar2);

在哪里

class Foo
{
  public:

    // Onwing ctor
    Foo(std::unique_ptr<Bar>&& b)
    : m_bar_ptr(std::move(b))
    {}

    // Viewing ctor. It uses shared_ptr aliasing ctor.
    Foo(Bar* b)
    : m_bar_ptr(nullptr, b)
    {}

  private:

    std::shared_ptr<Bar> m_bar_ptr;
  };

【讨论】:

    猜你喜欢
    • 2014-07-25
    • 2012-07-07
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多