如何有意地删除boost::shared_ptr?

45

我有许多boost::shared_ptr<MyClass>对象,某个时刻我有意删除其中的一些以释放一些内存。(此时我知道我将不再需要指向的MyClass对象。)我该怎么做?

我猜不能只使用get()获取裸指针并调用delete()

我在boost::shared_ptr中看到一个函数get_deleter(shared_ptr<T> const & p),但我不确定如何使用它,并且旁边还标注着实验性质。(我想我使用的是Boost 1.38。)

也许只需将变量分配给一个新的空boost::shared_ptr?这样应该会丢弃旧值并将其删除。


15
不要在调用 get() 后调用 delete。智能指针仍然拥有该对象的副本,并且将在释放该对象时调用 delete。 - Martin York
4个回答

83

你只需要这样做

ptr.reset();

请参阅shared_ptr手册。它与以下内容等效:

shared_ptr<T>().swap(ptr)

当智能指针不再引用对象时,您需要在每个智能指针上调用reset函数。最后一次使用reset(或者任何导致引用计数降为零的其他操作)会自动使用删除器释放对象。

也许您对智能指针编程技术感兴趣。其中有一个关于延迟释放的条目。


9
如果你希望能够有意地删除对象(我经常这样做),那么你必须使用单一所有权。如果使用shared_ptr与你的设计不相符,那么你就被诱导进去了。

8
boost::shared_ptr<T> 的核心是,只有当没有 shared_ptr<T> 指向它时,指针对象才会被删除,也就是说,当指向该对象的最后一个 shared_ptr<T> 超出作用域或重新分配为指向其他对象时。因此,要删除对象,只需确保没有 shared_ptr<T> 指向它即可。例如,如果您只有一个指向对象的 shared_ptr<T>,则让它超出作用域或调用 p.reset()(对于普通指针等效于 p = NULL),或将其赋值为指向其他东西。
如果有两个指向对象的 shared_ptr<T>,则需要重新分配这两个指针。
编辑:感谢 dehmann 指出 p = NULL; 实际上不是 shared_ptr<T> 的有效代码... :)

3
听起来不错,但是有一点需要注意:你不能写成p=NULL,因为p是一个shared_ptr而不是指针。 - Frank
1
是的,关于如何在使用shared_ptrs时使用NULL的相关问题,请参见https://dev59.com/dnRB5IYBdhLWcg3wcm6d#621249。 - m-sharp
@m-sharp:感谢提供链接。我在那个帖子上添加了一个答案,允许使用任何shared_ptr<T>类型的自然“p = nullPtr;”语法。 - j_random_hacker
那么为什么不允许使用p = nullptr语法呢?它似乎非常直观,比reset()更直观... - jiggunjer
@jiggunjer:我不知道,但我知道智能指针比关键字nullptr成为C++语言的一部分要早得多。允许使用p = nullptr 附加似乎不会有害...但是在C++中很多事情起初看起来都是这样的 :-/ - j_random_hacker

4
你需要做的是使用boost::weak_ptr返回弱引用,可以在需要时转换为shared_ptr。这可以让你控制shared_ptr中对象的生命周期,想要访问该对象的人可以持有weak_ptr并尝试转换为shared_ptr。如果转换失败,则可以重新查询并将对象带回内存。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接