C++11引入shared_ptr,unique_ptr,weak_ptr后,大大简化了c++对动态内存的管理,为了能更好的发挥智能指针的优势,且避免不必要的异常,下面总结了使用智能指针的的一些注意事项:
1.智能指针是行为像指针的类,其本质是一个类,其原理是通过构造/拷贝/赋值/析构操作来维护引用计数,从而达到对资源的管理,且该资源不仅仅限于动态内存;
比如:可以通过智能指针管理tcp的连接与端口;
{
int handle = tcp_nenect(ip_addr, port_num);
shared_ptr<int> p((int*)handle, [](int* h) {tcp_disconnect((int)h);}; //
//离开作用域时,自动断开连接
....
}
2.尽量不用get()函数返回智能指针保存的指针,而是直接采用解引用运算符(*/);
为了解决这个问题,是需要知道我们在什么情况下使用get(),及其对应的替换方式
情形一:智能指针类型为动态数组,通过get()返回头指针进行指针运算.(智能指针不支持),
此种情形最好将内置数组换成vector或array容器;
unique_ptr<int[]> parray(new int[10]);
int *begin = parray.get(); //通过get()返回头指针
int *end = begin + 10;
fill(begin, end, 10);
for_each(begin, end, [](const int& p) {
cout<< p << " ";
}); //打印 10 10 10 ...10
cout<<endl;
//采用解引用
for(int i = 0;i < 10; i++)
parray[i] = 12;
for(int i = 0;i < 10; i++)
cout<< parray[i] << " ";
情形二:通过指针访问指向对象的成员
shared_ptr<pair<string, int>> ps = make_shared<pair<string, int>>(string("hello"), 10);
auto* pp = ps.get(); //多此一举,不提倡的用法
cout<< pp->first << " " << pp->second << endl;
cout<< ps->first << " " << ps->second << endl; //简单方便
3.当需要管理多个相同元素时,不要用内置数组,建议使用vector或array容器;之所以不使用内置数组,
是由于shared_ptr<>不直接支持动态数组管理,且无法高效使用标准库
//shared_ptr类型为内置数组必须声明删除器为delete[]
shared_ptr<int> sp(new int[10], [](int*p) { delete[] p; } );
//建议方法
shared_ptr<vector<int>> sp = make_shared<vector<int>>(10, 1);
for_each(sp->begin(), sp->end(), [](int &e) {cout<< e << " "; } );
4.尽量不能混用普通指针和智能指针,尤其是以下几点:
①不使用相同的内置指针初始化(或reset)多个智能指针,正确方式如下:
shared_ptr<int> p(new int(10)); //ok,但提倡使用make_pair
p.reset(new int(42)); //ok
②不delete get()返回的指针③不使用get()初始化或reset另一个智能指针
④如果使用get()返回的指针,当对应的最后一个智能指针销毁后,此指针就无效了
反正上面四点记也挺麻烦,easy一点,就是别混用两者,甚至只使用智能指针;
5.使用make_pair初始化智能指针更简单,更安全shared_ptr<vector<int>> sp = make_shared<vector<int>>(10, 1); //运用的v(n, )构造
shared_ptr<pair<string, int>> ps = make_shared<pair<string, int>>(string("hello"), 10);
shared_ptr<vector<int>> sp = make_shared<vector<int>>(vector<int>{1,2,3,4,5}); //不能少vector<int>
6.采用typedef关键字定义智能指针类型避免表达式过长
//改写上面的表达式
typedef vector<int> vint ;
typedef shared_ptr<vector<int>> vi_sptr ;
vi_sptr sp1 = make_shared<vint>(10, 1);
vi_sptr sp2 = make_share<vint>(vint{1,2,3,4,5});
7.使用weak_ptr前请先lock()
//正确使用方式
if(share_ptr<int> np = wp.lock()) //如果np不为空则条件成立
{
//正常使用np进行操作
}