我有一个这样的课程:
部首:
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类实例。
所以我的问题是:
如果我像这样修改deleteSelf():
void CurlAsio::deleteSelf() {
delete this;
}
两个共享指针会发生什么?它们也会被删除吗?
答案 0 :(得分:4)
shared_ptr
成员有自己的析构函数来减少指针对象的引用计数,如果计数达到0,则delete
它。你不需要显式调用.reset()
无论如何,你的析构函数即将运行。
那就是说 - 为什么你甚至使用shared_ptr
?这些成员是否真的与其他对象共享?如果不是 - 请考虑unique_ptr
或按值存储。
至于内存 - 它通常不会返回到操作系统,直到您的程序终止,但可供您的内存重用。关于此,还有许多其他堆栈溢出问题。
如果你担心记忆,使用泄漏检测工具是个好主意。例如,在Linux上,valgrind非常出色。
答案 1 :(得分:1)
- 醇>
如果我像这样修改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