复制具有shared_ptr数据成员的类的构造函数

Copy constructor for class with shared_ptr data members?

本文关键字:数据成员 构造函数 ptr shared 复制      更新时间:2023-10-16

当类中有原始指针数据成员时,我知道如何编写复制构造函数,但当使用shared_ptr管理这些成员时,如何编写复制构造器?

是否有copy()clone()函数需要调用?有趣的是,我从未见过这样的例子。

std::shared_ptr的复制构造函数创建第二个指针,该指针与第一个指针共享所有权。当指向指针对象的所有std::shared_ptr都被销毁时,指针对象将被销毁。

如果没有显式声明的复制构造函数,语言规范会规定隐式提供一个合适的构造函数,并调用类中每个成员的复制构造函数。

因此,换句话说,为类提供的隐式复制构造函数将调用shared_ptr<T>::shared_ptr(const shared_ptr<T> &),它将创建指向同一对象的第二个共享指针,而这似乎不是您想要的。如果你想要一个指针对象的深度复制,你必须声明你自己的复制构造函数来创建一个:

class Foo
{
    Foo(const Foo &other)
      : foobar(new Bar(*other.foobar.get()))
    {}
    shared_ptr<Bar> foobar;
}

参考文献:

  • std::shared_ptr构造函数文档
  • 复制C++98(见12.8.8节)和C++11中的构造函数语义(见12.8.16节)

std::shared_ptr有自己的复制构造函数,它将处理托管共享数据的引用计数。

struct Foo {
    Foo(int i) : ptr{std::make_shared<int>(i)} {}
    std::shared_ptr<int> ptr;
};
int main() {
    Foo f1{0};
    Foo f2{f1}; // Using the implicitly generated copy ctor.
    *f1.ptr = 1;
    std::cout << *f1.ptr << std::endl; // 1 (data is shared).
    std::cout << *f2.ptr << std::endl; // 1 (data is shared).
}

如果您希望您的类具有resource所有权语义,那么只需将资源声明为具有自动存储持续时间的对象。

struct Foo2 {
    Foo2(int i) : i{i} {}
    int i; // Automatic object.
};
int main() {
    Foo2 f1{0};
    Foo2 f2{f1};
    f1.i = 1;
    std::cout << f1.i << std::endl; // 1
    std::cout << f2.i << std::endl; // 0
}