如果我删除课程,shared_ptr 会被删除吗
Posted
技术标签:
【中文标题】如果我删除课程,shared_ptr 会被删除吗【英文标题】:will the shared_ptr be deleted if i delete the class 【发布时间】:2015-05-31 03:18:32 【问题描述】:我有这样的课:
标题:
class CurlAsio
public:
boost::shared_ptr<boost::asio::io_service> io_ptr;
boost::shared_ptr<curl::multi> multi_ptr;
CurlAsio();
virtual ~CurlAsio();
void deleteSelf();
void someEvent();
;
Cpp:
CurlAsio::CurlAsio(int i)
id = boost::lexical_cast<std::string>(i);
io_ptr = boost::shared_ptr<boost::asio::io_service>(new boost::asio::io_service());
multi_ptr = boost::shared_ptr<curl::multi>(new curl::multi(*io_ptr));
CurlAsio::~CurlAsio()
void CurlAsio::someEvent()
deleteSelf();
void CurlAsio::deleteSelf()
if (io_ptr)
io_ptr.reset();
if (multi_ptr)
multi_ptr.reset();
if (this)
delete this;
在运行时,会创建和删除许多 CurlAsio 类的实例。
所以我的问题是:
-
即使我正在调用 shared_ptr.reset() ,是否有必要这样做?
我在运行时监控程序的虚拟内存使用情况,我预计在调用 deleteSelf() 后内存使用情况会下降,但事实并非如此。这是为什么呢?
如果我像这样修改 deleteSelf():
void CurlAsio::deleteSelf()
delete this;
这两个共享指针会发生什么?他们也会被删除吗?
【问题讨论】:
【参考方案1】:shared_ptr
成员有自己的析构函数来减少指针对象上的引用计数,如果计数达到 0,delete
会减少它。你不需要显式调用.reset()
,因为你的析构函数即将运行无论如何。
也就是说 - 你为什么还要使用shared_ptr
?这些成员真的与其他对象共享吗?如果没有 - 考虑 unique_ptr
或按值存储。
至于内存 - 在您的程序终止之前,它通常不会返回到操作系统,但可供您的内存重复使用。还有许多其他关于此的堆栈溢出问题。
如果您担心内存问题,使用泄漏检测工具是个好主意。例如,在 Linux 上,valgrind 非常出色。
【讨论】:
【参考方案2】:
如果我像这样修改 deleteSelf():
void CurlAsio::deleteSelf() delete this;
不要这样做。这是一种反模式。如果您发现自己“需要”这个,shared_from_this
是您的解决方案:
Live On Coliru
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
#include <vector>
struct X : boost::enable_shared_from_this<X>
int i = rand()%100;
using Ptr = boost::shared_ptr<X>;
void hold()
_hold = shared_from_this();
void unhold() _hold.reset();
~X()
std::cout << "~X: " << i << "\n";
private:
Ptr _hold;
;
int main()
X* raw_pointer = nullptr; // we abuse this for demo
auto some_x = boost::make_shared<X>();
// not lets addref from inside X:
some_x->hold();
// now we can release some_x without destroying the X pointed to:
raw_pointer = some_x.get(); // we'll use this to demo `unhold()`
some_x.reset(); // redundant since `some_x` is going out of scope here
// only the internal `_hold` still "keeps" the X
std::cout << "X on hold\n";
// releasing the last one
raw_pointer->unhold(); // now it's gone ("self-delete")
// now `raw_pointer` is dangling (invalid)
打印例如
X on hold
~X: 83
【讨论】:
以上是关于如果我删除课程,shared_ptr 会被删除吗的主要内容,如果未能解决你的问题,请参考以下文章