我知道如果在类中有原始指针数据成员时如何编写复制构造函数,但是当使用shared_ptr管理这些成员时,如何编写复制构造函数?
是否应该调用copy()
或clone()
函数?有趣的是,我从未见过这样的例子。
答案 0 :(得分:4)
std::shared_ptr
的复制构造函数创建了第二个指针,该指针与第一个指针共享所有权。当指向它的所有std::shared_ptr
都被销毁时,指针对象将被销毁。
如果没有显式声明复制构造函数,语言规范会声明将隐式提供一个合适的构造函数,并且它将调用类的每个成员的复制构造函数。
因此,换句话说,为您的类提供的隐式复制构造函数将调用shared_ptr<T>::shared_ptr(const shared_ptr<T> &)
,这将创建指向同一对象的第二个共享指针,并且它看起来不像&#39你想要的是什么。如果你想要一个深度的指针对象,你必须声明自己的复制构造函数,创建一个:
class Foo
{
Foo(const Foo &other)
: foobar(new Bar(*other.foobar.get()))
{}
shared_ptr<Bar> foobar;
}
参考文献:
答案 1 :(得分:3)
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).
}
如果您希望您的类具有资源所有权语义,那么只需将资源声明为具有自动存储持续时间的对象。
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
}