[英]Copy 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
}
我查看了文档;
复制和转换构造函数
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.
我不知道它是如何工作的 - 是这样的吗?
passed_ptr = shared_ptr(cached_ptr);
? const会去哪里? 他们分享所有权意味着什么? 那么它不是副本,如果我修改“pass_ptr”,更改会影响“cached_ptr”吗?
我找不到例子......请帮忙。
谢谢。
好吧,如果你有一个shared_ptr
并将它分配给另一个shared_ptr
,那么这两个共享指针将共享对象的所有权 - 这意味着指向对象所有权的引用计数将增加1。
实际上,在上面的行中,您根本不需要构造临时共享指针。 这就够了:
passed_ptr = cached_ptr;
无论如何,复制构造一个shared_ptr
基本上遵循相同的逻辑:你从一个共享指针开始,你最终得到两个共同拥有相同对象的共享指针(意味着只有当这两个共享指针时才会销毁该对象)被摧毁)。 所以当你这样做时:
passed_ptr = shared_ptr(cached_ptr);
实际上,你从给定对象的一个共享指针( cached_ptr
)开始,然后创建一个临时指针(将引用计数带到2),然后将其分配给passed_ptr
(将引用计数带到3),最终被销毁(将引用计数返回到2)。
在另一方面,如果你想要的是有passed_ptr
作为共享指向对象的副本被指向cached_ptr
,那么你应该宁愿做(假设Data
是可复制的,当然):
passed_ptr = boost::make_shared<Data>(*cached_ptr);
或者,或者:
passed_ptr.reset(new Data(*cached_ptr));
好的。 让我们看看我们是否可以谈论这个问题。
std::shared_ptr<Data> x = std::make_shared<Data>();
std::shared_ptr<Data> y = x;
assert(x.get() == y.get());
如果我改变x
指向的内容,那么也会改变关于y
信息。 因为他们指向同一件事。
x->member = 3;
assert(x->member == 3);
assert(y->member == 3);
我可以改变x
指向的内容而不改变y
指向的内容。
x = std::make_shared<Data>();
assert(x.get() != y.get());
如果我这样做,那么对x
更改不会反映到y
。 因为他们指向不同的东西。
x->member = 4;
assert(x->member == 4);
assert(y->member != 4);
如果我想复制x
的内容,并将其存储在y
,那么我需要创建一个新的共享对象。
y = std::make_shared<Data>(*x);
此时, x
和y
都将该成员变量设置为4.因为x
已将其设置,并且我们使用*x
的内容创建了*y
。
assert(x->member == 4);
assert(y->member == 4);
但是,因为x
和y
指向内存中的不同内容,我们可以更改其中一个。
assert(x.get() != y.get();
x->member = 3;
assert(x->member == 3);
assert(y->member == 4);
如果我要将shared_ptr传递给函数,那就像第一种情况一样。
void func(std::shared_ptr<Data> z) {
assert(x.get() == z.get());
}
func(x);
我还可以使用reset()
释放特定shared_ptr的内容。 这将导致shared_ptr指向的值变为NULL。
x.reset();
assert(x.get() == NULL);
关于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.
通常的惯例是传递const shared_ptr
:
bool
someWork( data_ptr const& passed_ptr )
{
// ...
}
这允许使用指针(包括复制和转换它),但不能修改它。
如果要更改指针指向调用站点的内容,则必须传递非const引用。 这里最简单的策略是,恕我直言,为它分配新值,但你也可以调用reset
功能。
至于它是如何工作的:当你将指针传递给引用参数时,你只需要给被调用函数访问原始指针。 在引擎盖下,它非常像一个系统地解除引用的指针。 你似乎把指针与它指向的东西混淆了; 它指向的是共享,而不是指针本身。 指针本身的行为与任何其他C ++对象完全相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.