用智能指针的一个注意点
最近自己用c++写socks5服务器,中间试图用智能指针来控制client类的分配与释放。达到在连接断开时,自动释放socket等资源的目的。但是写的过程中,发现用智能指针时,要尤其注意什么时候会让智能指针的计数为0,从而出发析构函数。示例代码如下:
#include <bits/stdc++.h>
using namespace std;
class A
{
public:
int a;
A()
{
a = 3;
}
void remove_first(vector<shared_ptr<A>>& v)
{
if(v.size()>=1)
v.erase(v.begin());
cout<<"a = "<<a<<" from A::remove_first"<<endl;
}
~A()
{
a = 5;
cout<<"destructor"<<endl;
}
};
int main()
{
vector<shared_ptr<A>> v;
{
shared_ptr<A> p = make_shared<A>();
v.push_back(p);
}
v.front()->remove_first(v);
return 0;
}
可以将A看作要管理的资源,v是容器。在A::remove_first这个函数中,需要注意对v的操作可能让自己的智能指针被析构,从而导致自己被析构,类似delete this的感觉。
这段程序在gcc8编译后运行的结果是
destructor
a = 5 from A::remove_first
说明的确在执行了析构函数,并且a的值也被改变了。试试上析构以后,a的值就是未定义的了。
总结下,当用智能指针管理对象时,如果对象中涉及到对智能指针的释放,要考虑到释放的是不是自己,如果是自己,就要考虑到自己被析构以后就不能再使用任何对象成员变量了,因为析构以后这些都是未定义的了。