c++ shared_ptr智能指针使用注意事项
上一篇 / 下一篇 2012-09-19 09:30:50 / 个人分类:C++
shared_ptr在boost中地位相当重要,其行为最接近原始指针,但又比指针更加安全,甚至还能提供基本的线程安全保证。它基本上解决 了在使用c++开发过程中不可避免的使用指针而遇到的许多问题,常见的毫无疑问是内存泄漏和内存的提前释放,还有一些关于指针内存申请而产生的异常问题 等。而要想较好的使用shared_ptr来完全取代指针绝非易事。下面简要说说使用shared_ptr需要注意的问题。51Testing软件测试网O {I7o g:~@F
0D!\8q:jqXw0 1、share_ptr是一个类,它产生的是一个类对象,而不是一个原生的指针对象,但是为了减少类对象与针对对象使用的差异性,所以 share_ptr类故意重载了两种常见的指针操作符: *和->。从而share_ptr与普通指针使用方式一样。简言之,就是share_ptr生成的一个包含类型指针容器对象,它封装了指针对象,对 指针对象负全责,包括生成、释放等;51Testing软件测试网!OVmQ!Qk
51Testing软件测试网udil%u3V,eR2、特别需要注意的是,share_ptr的转型函数不能使用c++常用的转型函数,即 static_cast,dynamic_cast,const_cast,而要使用 static_pointer_cast,dynamic_pointer_cast,const_pointer_cast。原因有两 个:static_cast,dynamic_cast,const_cast的功能是转换成对应的模版类型,即 static_cast<T*>其实是转换成类型为T的指针;前面说了share_ptr生成的一个包含类型指针容器对象,使用简单的c++ 转型函数是将share_ptr对象转型为模版指针对象,这完全违背了使用share_ptr的初衷(除非你确确实实有这种需要!),导致转型的模版指针 对象不能采用share_ptr进行管理。因为上面的两个原因:share_ptr为了支持转型,所以提供了类似的转型函数即 static_pointer_cast<T>,从而使转型后仍然为shared_pointer对象,仍然对指针进行管理;51Testing软件测试网_"Qp9pyn5yCw
u0| Yo'_8S2W0 3、share_ptr类重载了许多的构造函数,其中包含无参的构造函数用来创建一个持有空指针的share_ptr对象,,注意它不等价于持 有void*型的指针对象。要想生成一个存储void*型的指针,可以使用share_ptr(void*)构造函数来构造,它相当于一个泛型的指针容 器,拥有容纳任意类型的能力,但是将包含void*指针的shared_ptr对象使用注意2中的转型函数转型为某种类型的指针会使代码不够安全,一般不 要使用;
l W5B(b{Q051Testing软件测试网9n|z"p5Wb4、share_ptr完美支持标准容器,并且不需要担心资源泄漏。而标准容易在使用指针对象时需要特别的小心,对指针需要额外的管理。下面用代码范例来演示如何将share_ptr应用与标准容器:
*S0xtU3x|0U2zh051Testing软件测试网? x~ JB&{1e$Ce51Testing软件测试网w/YEb @K~C
<SPAN style="FONT-SIZE: 14px"><STRONG>#include <boost/make_shared.hpp>51Testing软件测试网:t{!m+E.y*G*A #include <vector> 'P2D/ZdV&Y%X/F0using namespace std; 1FX7b9{'lD0using namespace boost; ~f M~4pm^4D0int main ()51Testing软件测试网;X!u|1W6oX2nR { 0q UV.F.m'N&EHF0 typedef vector< shared_ptr<int> > sharedContainers; gDL'b7l#X#Vc0 sharedContainers sharedArray(10); 6c0tb[;]-G `0 for(sharedContainers::interator pos = sharedArray.begin() , int i=0 ;pos!=sharedArray.end();++pos) *X7_(qRn`%p0 {51Testing软件测试网]^:?'z3lK6{"kr *pos = make_shared<int>(++i); jp k1Yt#]0 cout<<*(*pos)<<"\t"; ;^ h S)I$EJ0J(H1v0 } {l8FIp,C0s0 cout<<endl; t5~4S0y8jj0}</STRONG></SPAN> |
#mR^-e~%R0 注意上面的代码中的头文件#include <boost/make_shared.hpp>,不是常见的#include <boost/smart_ptr.hpp>,这是因为make_shared.hpp中提供了一个自由工厂函数 make_shared<T>(),来消除显示的new调用,其实是模仿了标准库中产生pair的函数make_pair().因为 make_shared.hpp中包含了smart_ptr.hpp,所以加入了make_shared.hpp就不需要再声明 smart_ptr.hpp头文件了。而smart_ptr.hpp没有包含make_shared.hpp,所以必须要单独写出 make_shared.hpp。
[-_o:c*`| r051Testing软件测试网V*eQ:zV.s;C3d&G5、share_ptr使用赋值操作符可以从另外一个share_ptr或auto_ptr获得指针的管理权,其行为等同于构造函数,但它完全 不能等同于一种拷贝,只是将原来的对象的引用技术加1,说白了就是共享资源;而实际的指针赋值确是一种浅拷贝操作,关于深拷贝与浅拷贝可参与该篇文章:渐析java的浅拷贝和深拷贝。下面用代码范例来share_ptr的赋值和复制操作:(继续上面的例子)
'BK$dE7VQ0+fc?`M051Testing软件测试网%\4Qh'c:q ~F
O4@oQ+a
K S3w0<SPAN style="FONT-SIZE: 14px"><STRONG>#include <boost/make_shared.hpp>51Testing软件测试网E/H`,p7z k Q,ooc int main (int argc, const char * argv[]) |