如果我删除 class,shared_ptr 会被删除吗
will the shared_ptr be deleted if i delete the class
我有一个这样的 class :
Header:
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 Class 实例。
所以我的问题是:
- 即使我正在调用 shared_ptr.reset() ,是否有必要这样做?
- 我在 运行 期间监控程序的虚拟内存使用情况,我希望在调用 deleteSelf() 后内存使用情况会下降,但事实并非如此。这是为什么?
如果我像这样修改 deleteSelf():
void CurlAsio::deleteSelf() {
delete this;
}
两个共享指针发生了什么?他们也会被删除吗?
shared_ptr
成员有自己的析构函数来减少 pointee 对象的引用计数,delete
如果计数达到 0,它会减少。你不需要调用 .reset()
明确地给出了你的析构函数即将 运行 无论如何。
就是说 - 为什么还要使用 shared_ptr
?这些成员真的与其他对象共享吗?如果不是 - 考虑 unique_ptr
或按值存储。
至于内存 - 在您的程序终止之前,它通常不会返回给操作系统,但可供您的内存重用。关于这个还有很多其他的堆栈溢出问题。
如果您担心内存问题,使用泄漏检测工具是个好主意。例如,在 Linux 上,valgrind 非常出色。
if i modify the deleteSelf() like this:
void CurlAsio::deleteSelf() {
delete this;
}
不要这样做。这是一个反模式。如果您发现自己 "needing" 这个,shared_from_this
就是您的解决方案:
#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
我有一个这样的 class :
Header:
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 Class 实例。
所以我的问题是:
- 即使我正在调用 shared_ptr.reset() ,是否有必要这样做?
- 我在 运行 期间监控程序的虚拟内存使用情况,我希望在调用 deleteSelf() 后内存使用情况会下降,但事实并非如此。这是为什么?
如果我像这样修改 deleteSelf():
void CurlAsio::deleteSelf() { delete this; }
两个共享指针发生了什么?他们也会被删除吗?
shared_ptr
成员有自己的析构函数来减少 pointee 对象的引用计数,delete
如果计数达到 0,它会减少。你不需要调用 .reset()
明确地给出了你的析构函数即将 运行 无论如何。
就是说 - 为什么还要使用 shared_ptr
?这些成员真的与其他对象共享吗?如果不是 - 考虑 unique_ptr
或按值存储。
至于内存 - 在您的程序终止之前,它通常不会返回给操作系统,但可供您的内存重用。关于这个还有很多其他的堆栈溢出问题。
如果您担心内存问题,使用泄漏检测工具是个好主意。例如,在 Linux 上,valgrind 非常出色。
if i modify the deleteSelf() like this:
void CurlAsio::deleteSelf() { delete this; }
不要这样做。这是一个反模式。如果您发现自己 "needing" 这个,shared_from_this
就是您的解决方案:
#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