【问题标题】:shared_ptr member and copy constructorsshared_ptr 成员和复制构造函数
【发布时间】:2014-09-08 21:39:11
【问题描述】:

我正在编写一个 C++ 库,并希望隐式共享其中一个类。不幸的是,我对它的实现有点困惑。我想使用std::shared_ptr 来存储数据,我想知道下面的代码是否缺少任何内容。

// MyClass.h
class MyClass
{
public:
    MyClass (void);

private:
    class Data;
    std::shared_ptr<Data> mData;
};

// MyClass.cc
class MyClass::Data
{
public:
     Data (void) { ptr = NULL; }
    ~Data (void) { delete ptr; }
    int* ptr;
};

MyClass::MyClass (void)
    : mData (new MyClass::Data())
{
    mData->ptr = new int(5);
}

查看其他人的代码,我注意到他们添加了复制/移动构造函数/操作符(使用 std::move 等)和一个空的析构函数。其中一个 cmets 提到 MyClass 需要一个空的析构函数,以便编译器注意到 MyClass::Data 的析构函数。这些真的有必要吗,还是上面的代码足够好?默认的复制/移动构造函数/操作符和析构函数是否足够好?

【问题讨论】:

  • 如果你想共享mData指向的数据,那么你不需要复制构造函数和赋值运算符,默认的就可以了。
  • 为什么不使用std::unique_ptrstd::shared_ptr 作为MyClass::Data::ptr 成员?
  • @KerrekSB 我已经尝试过了,它看起来可以正常工作,但很好验证,因为我以前被这类事情困住了。
  • @RemyLebeau 这只是一个例子,实际的Data类有点复杂,需要一个显式的析构函数。
  • 您是否尝试过使用多个翻译单元?

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


【解决方案1】:

您的代码很好。如果您想深度复制数据,您可能需要声明一个复制构造函数,但这违背了使用共享指针的目的。 空的析构函数注释是完整的 BS。如果您不提供析构函数,则将使用默认析构函数 - 在任何情况下,成员类的析构函数都会被调用。

当您看到人们需要在 MyClass.cc 中显式默认其析构函数(和赋值运算符)时,那是因为他们使用的是 std::unique_ptr 而不是 std::shared_ptr。如果您切换到使用std::unique_ptr&lt;Data&gt;,您会看到编译器提供的析构函数等在他们在范围内找不到~Data 的定义时会出错。但是std::shared_ptr是不允许吐的。

【讨论】:

  • 是的,我就是这么想的,这就是为什么当我看到人们这样做时我感到困惑的原因。 Here 是我提出的问题的一个示例,您可以看到它按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 2021-08-28
  • 2013-03-27
  • 1970-01-01
相关资源
最近更新 更多