2013-05-07 79 views
5
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 
} 

我看了文档;复制boost :: shared_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会去哪里?这是什么意思,他们分享所有权?那么它不是副本,如果我修改“passed_ptr”,更改会影响“cached_ptr”?

我找不到示例...请帮助。

谢谢。

回答

10

好吧,如果你有一个shared_ptr,你把它分配给另一个shared_ptr,这两个共享指针将共享对象的所有权 - 意为尖锐的物体的所有权引用计数将增加一个。

事实上,在上面的线,你不需要建立一个临时共享指针都没有。这是不够的:

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)); 
+0

我想要一个实际的副本,而不是2个指针指向同一个对象当我修改passed_ptr的数据时,cached_ptr的数据应该保持不变 – Thalia 2013-05-07 16:20:58

+0

@Thalia:我扩展了我的答案来涵盖这个 – 2013-05-07 16:23:23

+0

谢谢,我在提出这个问题之前看到了这个,并试图用“重置“,但它不可用 – Thalia 2013-05-07 16:25:56

1

通常的惯例是通过一个const shared_ptr

bool 
someWork(data_ptr const& passed_ptr) 
{ 
    // ... 
} 

这允许使用指示器(包括复制和转换 ),但不修改它。

如果您想要在呼叫 网站上更改指针指向的内容,则必须传递非const引用。这里最简单的 政策是,恕我直言,分配新的价值,但你也可以 也叫reset函数。

至于它是如何工作的:当您将指针传递给参考 参数时,您只需将被调用的函数访问到原始指针即 。在引擎盖下,它非常类似于 这是一个系统地解引用的指针。而你似乎将指针与它指向的内容混淆在一起;它正是它共享的内容,而不是指针本身。指针本身 的行为与任何其他C++对象完全相同。

+0

我没能常量,因为它的内容会改变 - 如果我让常量,我还可以改变它包含的数据? – Thalia 2013-05-07 16:17:55

+0

@Thalia:你不能改变指针本身的状态(例如分配),但你可以改变对象的状态被指向 – 2013-05-07 16:18:37

+0

所以我如何才能复制到passed_ptr的内容cached_ptr的内容 - 没有分配一个指针到另一个? – Thalia 2013-05-07 16:18:57

9

好的。让我们看看我们是否可以谈论这个。

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); 

在这一点上,无论是xy有一个成员变量设置为4。由于x有它设置,并且我们与*x内容创建*y

assert(x->member == 4); 
assert(y->member == 4); 

但是,由于xy在内存中指向不同的东西,我们可以改变其中的一个。

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 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. 
相关问题