智能指针使用Tip

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进行操作
}





阅读更多
个人分类: C/C++
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭