auto_ptr 与 shared_ptr 用法和区别总结

一、std::auto_ptr 被复制后,将失去原来所致资源的所有权;*auto_ptr在头文件<memory>中。

永不建立auto_ptr的容器
关于此可以看的Effective STL的条款8

因为auto_ptr并不是完美无缺的,它的确很方便,但也有缺陷,在使用时要注意避免。

首先,不要将auto_ptr对象作为STL容器的元素。C++标准明确禁止这样做,否则可能会碰到不可预见的结果

auto_ptr的另一个缺陷是将数组作为auto_ptr的参数: auto_ptr<char>  pstr (new char[12] ); //数组;为定义
然后释放资源的时候不知道到底是利用delete pstr,还是 delete[] pstr;

然后收集了关于auto_ptr的几种注意事项:
1、auto_ptr不能共享所有权。
2、auto_ptr不能指向数组
3、auto_ptr不能作为容器的成员。
4、不能通过赋值操作来初始化auto_ptr
std::auto_ptr<int> p(new int(42));     //OK
std::auto_ptr<int> p = new int(42);    //ERROR,本想通过new int(42)来产生临时对象temp(问题出在这里),再由temp拷贝构造产生p。
这是因为auto_ptr 的构造函数被定义为了explicit

std::auto_ptr<int> p = auto_ptr<int>(new int(42)); //Success   
5、不要把auto_ptr放入容器

二、std::tr1::shared_ptr 是可以共享所有权的智能指针;(推荐使用)

*shared_ptr在boost的头文件模块中.在vs最新的编译器己可用.但在vc6上却找不到该模块.

1. shared_ptr是Boost库所提供的一个智能指针的实现,shared_ptr就是为了解决auto_ptr在对象所有权上的局限性(auto_ptr是独占的),在使用引用计数的机制上提供了可以共享所有权的智能指针.
2. shared_ptr比auto_ptr更安全
3. shared_ptr是可以拷贝和赋值的,拷贝行为也是等价的,并且可以被比较,这意味这它可被放入标准库的一般容器(vector,list)和关联容器中(map)。

关于shared_ptr的使用其实和auto_ptr差不多,只是实现上有差别,关于shared_ptr的定义就不贴代码了,以为内开源,可以网上找
1、shared_ptr<T> p(new Y);

再来说说shared_ptr的缺点。

1.对于使用引用计数的智能指针来说,必须要小心出现循环引用。
     在重度使用shared_ptr的系统中,你必须一开始就明确类与类的关系,以决定哪里使用shared_ptr,哪里使用weak_ptr,否则就会出现内存泄露。而shared_ptr的接口转换的灵活性,也很容易导致智能指针被滥用。内存自动管理的问题并没有得到解决,它只是被转移了。

2.shared_ptr使用非嵌入式设计,这样可以使用于基本类型,比如 shared_ptr<int>。但是根据个人经验,这种情况在很少使用。大部分情况还是使用自己设计的类。这有一个问题,就是没有很方便的办法实现this指针和智能指针的转换。标准库中提供了enable_shared_from_this类来解决这个问题。但这已经使所谓的非嵌入式设计徒有虚名。而假如一开始采用嵌入式设计的话,则在性能代价和多线程设计方面具有更大的灵活性。

要了解更多关于auto_ptr的信息,可以查看more effective c++ 的p158页条款28
要了解shared_ptr 类模板信息,可以查看boost 1.37.0中文文档,而且支持数组的shared_array 类模板

 

1>为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源.如下:

void Func()

{

   Investment* pInv = createInvestment();//createInvestment是工厂方法.返回一个堆上的对象指针

   ...;

   delete pInv;

}

这时当在...区域一个过早的return,continue,goto语句退出.这样在区域内的语句抛出异常,这样delete就被忽略过去,这时就发生了内存泄漏,我们泄漏的不只是内含对象的那块内存,还包括那些对象所保存的任何资源.

*为确保createInvestment返回的资源总是被释放,我们需要将资源放进对象内,当控制流离开了Func(),该对象的析构函数会自动释放那些资源.这就是把资源放进对象内.如下:

void Func()

{

   std::auto_ptr<Invesment> pInv(createInvestment()); //auto_ptr"以对象管理资源"

}

2>两个常被使用的RAII classes分别是tr1::shared_ptr和auto_ptr.前者是较好的选择,由于auto_ptr被销毁时会自动删除它所指之物,所以一定要注意别让多个auto_ptr同时指向同一个对象,若通过copy构造函数或copy assignment操作符复制它们,它们会变成null,而复制所得的指针将取得资源的唯一拥有权.如下:

void Func1()

{

  std::auto_ptr<Investment> pInv1(createInvestment());//pInv1指向工厂函数createInvestment返回物

  std::auto_ptr<Investment> pInv2(pInv1);             //现在pInv2指向上述对象,但pInv1被设为null了

  pInv1 = pInv2;                                   //现在pInv1指向上述对象了.pInv2被设为null了

}

但tr1::shared_ptr却可以保证多个对象指向同一笔资源,并在无人指向它时自动删除该资源.如下

void Func1()

{

   std::tr1::shared_ptr<Investment> pInv1(createInvestment());//pInv1指向crateInvestment返回物

   std::tr1::shared_ptr<Investment> pInv2(pInv1); //pInv1和pInv2指向同一个对象

   pInv1 = pInv2;  //同上,无任何改变

}//函数结束后,pInv1和pInv2被销毁,它们所指的对象也被自动销毁

*auto_ptr在头文件<memory>中

*shared_ptr在boost的头文件模块中.在vs最新的编译器己可用.但在vc6上却找不到该模块.


版权声明:本文为weixin_43778179原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>