复制boost :: shared_ptr

Tha*_*lia 5 c++ boost shared-ptr

typedef boost::shared_ptr<SomeData> data_ptr;
data_ptr cached_ptr;   // class member 
bool someWork(data_ptr& passed_ptr)
{
  // must copy passed_ptr = cached_ptr under some conditions
  // without pointing at the same memory 
  // I saw somewhere that I should do 
  // passed_ptr.reset(new SomeData(???))
  // I don't have a "reset" on passed_ptr
}
Run Code Online (Sandbox Code Playgroud)

我查看了文档;

复制和转换构造函数

shared_ptr(shared_ptr const & r); // never throws
template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
Requires: Y* should be convertible to T*.

Effects: If r is empty, constructs an empty shared_ptr; otherwise,
         constructs a shared_ptr that shares ownership with r.
Run Code Online (Sandbox Code Playgroud)

我不知道它是如何工作的 - 是这样的吗?

passed_ptr = shared_ptr(cached_ptr);
Run Code Online (Sandbox Code Playgroud)

?const会去哪里?他们分享所有权意味着什么?那么它不是副本,如果我修改"pass_ptr",更改会影响"cached_ptr"吗?

我找不到例子......请帮忙.

谢谢.

And*_*owl 12

好吧,如果你有一个shared_ptr并将它分配给另一个shared_ptr,那么这两个共享指针将共享该对象的所有权 - 这意味着指向对象所有权的引用计数将增加一.

实际上,在上面的行中,您根本不需要构造临时共享指针.这就够了:

passed_ptr = cached_ptr;
Run Code Online (Sandbox Code Playgroud)

无论如何,复制构造a shared_ptr基本上遵循相同的逻辑:你从一个共享指针开始,你最终得到两个共同拥有相同对象的共享指针(意味着只有当这两个共享指针都得到时,对象才会被销毁)破坏).所以当你这样做时:

passed_ptr = shared_ptr(cached_ptr);
Run Code Online (Sandbox Code Playgroud)

实际上你从cached_ptr给定对象的一个共享指针()开始,然后创建一个临时指针(将引用计数带到2),然后将其分配给passed_ptr(将引用计数带到3),最终被销毁(带来引用计数回到2).

另一方面,如果你想要的是passed_ptr作为指向对象副本的共享指针cached_ptr,那么你应该做(假设Data是可复制的,当然):

passed_ptr = boost::make_shared<Data>(*cached_ptr);
Run Code Online (Sandbox Code Playgroud)

或者,或者:

passed_ptr.reset(new Data(*cached_ptr));
Run Code Online (Sandbox Code Playgroud)


Bil*_*nch 9

好的.让我们看看我们是否可以谈论这个问题.

std::shared_ptr<Data> x = std::make_shared<Data>();
std::shared_ptr<Data> y = x;

assert(x.get() == y.get());
Run Code Online (Sandbox Code Playgroud)

如果我改变了什么x指向什么,那也会改变信息y.因为他们指向同一件事.

x->member = 3;
assert(x->member == 3);
assert(y->member == 3);
Run Code Online (Sandbox Code Playgroud)

我可以x在不改变y指向的情况下改变指向的内容.

x = std::make_shared<Data>();
assert(x.get() != y.get());
Run Code Online (Sandbox Code Playgroud)

如果我这样做,那么更改将x不反映到y.因为他们指向不同的东西.

x->member = 4;
assert(x->member == 4);
assert(y->member != 4);
Run Code Online (Sandbox Code Playgroud)

如果我想复制内容x,并将其存储y,那么我需要创建一个新的共享对象.

y = std::make_shared<Data>(*x);
Run Code Online (Sandbox Code Playgroud)

在这一点上,无论是xy有成员变量设置为4.由于x有这个设定,我们创造了*y与内容*x.

assert(x->member == 4);
assert(y->member == 4);
Run Code Online (Sandbox Code Playgroud)

但是,因为x并且y在内存中指向不同的东西,我们可以改变其中一个.

assert(x.get() != y.get();
x->member = 3;
assert(x->member == 3);
assert(y->member == 4);
Run Code Online (Sandbox Code Playgroud)

如果我要将shared_ptr传递给函数,那就像第一种情况一样.

void func(std::shared_ptr<Data> z) {
    assert(x.get() == z.get());
}

func(x);
Run Code Online (Sandbox Code Playgroud)

我也可以通过使用释放特定shared_ptr的内容reset().这将导致shared_ptr指向的值变为NULL.

x.reset();
assert(x.get() == NULL);
Run Code Online (Sandbox Code Playgroud)

关于const正确性,它有点奇怪.

const std::shared_ptr<Data> x;
x.reset(); // Fails because the shared_ptr is const.
x->member = 3; // Succeeds because Data is not const.

std::shared_ptr<const Data> x;
x.reset(); // Succeeds because the shared_ptr is not const.
x->member = 3; // Fails because Data is const.
Run Code Online (Sandbox Code Playgroud)