智能指针 boost(scoped_ptr,scoped_array,shared_ptr,shared_array) 和 std (auto_ptr)的比较 .

news/2024/7/6 1:37:57 标签: string, 多线程, delete, class
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

 http://blog.csdn.net/afrish/article/details/3985471

 

 

class="article_title"> class="ico ico_type_Original">

class="link_title">智能指针 boost(scoped_ptr,scoped_array,shared_ptr,shared_array) 和 std (auto_ptr)的比较

class="article_manage"> class="link_categories">分类: BOOST class="link_postdate">2009-03-12 22:09 class="link_view" title="阅读次数"> 658人阅读 class="link_comments" title="评论次数">评论(0) class="link_collect">收藏 class="link_report"> 举报
class="article_content">

1、std::auto_ptr

std::auto_ptr相信都接触使用过,对于一般的用户它绝对够用了,new一块内存自动释放

 

例如:

class="dp-highlighter bg_cpp">
class="bar">
class="tools"> view plain copy to clipboard print ?
    class="dp-cpp">
  1. class="alt">class="datatypes">int main()  
  2. {  
  3. class="alt">  std::auto_ptr<class="datatypes">int> p(class="keyword">new class="datatypes">int);  
  4.   
  5. class="alt">  class="keyword">return 0;  
  6. }  

 

 但它的不足之处在与,对象拥有者只有一个,换句话说:就是new出来的内存空间只属于一个对象

 

例如:

class="dp-highlighter nogutter bg_cpp:nogutter:firstline[2]">
class="bar">
class="tools"> view plain copy to clipboard print ?
    class="dp-cpp" start="2">
  1. class="alt">class="datatypes">int main()  
  2. {  
  3. class="alt">   std::auto<str::class="tags" href="/tags/STRING.html" title=string>string> p(class="keyword">new class="tags" href="/tags/STRING.html" title=string>string(class="class="tags" href="/tags/STRING.html" title=string>string">"123"));  
  4.    std::auto<str::class="tags" href="/tags/STRING.html" title=string>string> p1(p);  
  5. class="alt">  
  6.    cout << p << endl; class="comment">// p的值已近为空   
  7. class="alt">   cout << p1 << endl; class="comment">// 123   
  8. }  

 

2、scoped_ptr、scoped_array

 

scoped_ptr与auto_ptr相似, scoped_ptr智能指针与std::auto_ptr不同在于,它明确禁止任何想要这样做的企图!这在你需要确保指针任何时候只有一个拥有者时的任何一种情境下都是非常重要的

 

scoped_ptr通过成员还是的private私有化来禁止拷贝 nocopyable

class="dp-highlighter bg_c-sharp">
class="bar">
class="tools"> view plain copy to clipboard print ?
    class="dp-c">
  1. class="alt">class="keyword">class noncopyable  
  2. {  
  3. class="alt">   class="keyword">protected:  
  4.       noncopyable() {}  
  5. class="alt">      ~noncopyable() {}  
  6.    class="keyword">private:  class="comment">// emphasize the following members are private   
  7. class="alt">      noncopyable( class="keyword">const noncopyable& );  
  8.       class="keyword">const noncopyable& class="keyword">operator=( class="keyword">const noncopyable& );  
  9. class="alt">};  

 

scoped_array与scoped_ptr显然是意义等价的,但是是用来处理数组的

 

3、shared_ptr,shared_array

 

boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而   boost::shared_ptr可以解决这一局限。顾名思义,boost::shared_ptr是可以共享所有权的智能指针,首先让我们通过一个例子看看它的基本用法:

class="dp-highlighter bg_c-sharp">
class="bar">
class="tools"> view plain copy to clipboard print ?
    class="dp-c">
  1. class="alt">class="preprocessor">#include <class="tags" href="/tags/STRING.html" title=string>string> class="preprocessor"> 
  2. class="preprocessor">#include <iostream> class="preprocessor"> 
  3. class="alt">class="preprocessor">#include <boost/shared_ptr.hpp>   
  4.   
  5. class="alt">class="keyword">class implementation  
  6. {  
  7. class="alt">class="keyword">public:  
  8.     ~implementation() { std::cout <<class="class="tags" href="/tags/STRING.html" title=string>string">"destroying implementation/n"; }  
  9. class="alt">    class="keyword">void do_something() { std::cout << class="class="tags" href="/tags/STRING.html" title=string>string">"did something/n"; }  
  10. };  
  11. class="alt">  
  12. class="keyword">void test()  
  13. class="alt">{  
  14.     boost::shared_ptr<implementation> sp1(class="keyword">new implementation());  
  15. class="alt">    std::cout<<class="class="tags" href="/tags/STRING.html" title=string>string">"The Sample now has "<<sp1.use_count()<<class="class="tags" href="/tags/STRING.html" title=string>string">" references/n";  
  16.   
  17. class="alt">    boost::shared_ptr<implementation> sp2 = sp1;  
  18.     std::cout<<class="class="tags" href="/tags/STRING.html" title=string>string">"The Sample now has "<<sp2.use_count()<<class="class="tags" href="/tags/STRING.html" title=string>string">" references/n";  
  19. class="alt">      
  20.     sp1.reset();  
  21. class="alt">    std::cout<<class="class="tags" href="/tags/STRING.html" title=string>string">"After Reset sp1. The Sample now has "<<sp2.use_count()<<class="class="tags" href="/tags/STRING.html" title=string>string">" references/n";  
  22.   
  23. class="alt">    sp2.reset();  
  24.     std::cout<<class="class="tags" href="/tags/STRING.html" title=string>string">"After Reset sp2./n";  
  25. class="alt">}  
  26.   
  27. class="alt">class="keyword">void main()  
  28. {  
  29. class="alt">    test();  
  30. }   
 

该程序的输出结果如下:

The Sample now has 1 references
The Sample now has 2 references
After Reset sp1. The Sample now has 1 references
destroying implementation
After Reset sp2.

可以看到,boost::shared_ptr指针sp1和sp2同时拥有了implementation对象的访问权限,且当sp1和sp2都释放对该对象的所有权时,其所管理的的对象的内存才被自动释放。在共享对象的访问权限同时,也实现了其内存的自动管理。

boost::shared_ptr的内存管理机制:

boost::shared_ptr的管理机制其实并不复杂,就是对所管理的对象进行了引用计数,当新增一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数加一;减少一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数减一,如果该对象的引用计数为0的时候,说明没有任何指针对其管理,才调用class="tags" href="/tags/DELETE.html" title=delete>delete释放其所占的内存。

上面的那个例子可以的图示如下:

  1. sp1对implementation对象进行管理,其引用计数为1
  2. 增加sp2对implementation对象进行管理,其引用计数增加为2
  3. sp1释放对implementation对象进行管理,其引用计数变为1
  4. sp2释放对implementation对象进行管理,其引用计数变为0,该对象被自动删除

boost::shared_ptr的特点:

和前面介绍的boost::scoped_ptr相比,boost::shared_ptr可以共享对象的所有权,因此其使用范围基本上没有什么限制(还是有一些需要遵循的使用规则,下文中介绍),自然也可以使用在stl的容器中。另外它还是线程安全的,这点在class="tags" href="/tags/DuoXianCheng.html" title=多线程>多线程程序中也非常重要。

boost::shared_ptr的使用规则:

boost::shared_ptr并不是绝对安全,下面几条规则能使我们更加安全的使用boost::shared_ptr:

  1. 避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放
  2. shared_ptr并不能对循环引用的对象内存自动管理(这点是其它各种引用计数管理内存方式的通病)。
  3. 不要构造一个临时的shared_ptr作为函数的参数。
    如下列代码则可能导致内存泄漏:
    void test()
    {
        foo(boost::shared_ptr<implementation>(new    implementation()),g());
    }
    正确的用法

    void test()
    {
        boost::shared_ptr<implementation> sp    (new implementation());
        foo(sp,g());
    }

 

 


http://www.niftyadmin.cn/n/790304.html

相关文章

eclipse debug调试java程序的九个技巧

九个技巧&#xff1a; 逻辑结构条件debug异常断点单步过滤跳到帧Inspectexpressionsdisplay远程debug最早开始用eclipse的debug的时候&#xff0c;只会F5 F6 F7 F8&#xff0c;甚至F7都不是很搞的明白是怎么用的&#xff0c;那时候资浅&#xff0c;碰不到需要复杂debug的代码&a…

【转】Android开源项目(非组件)

原文网址&#xff1a;http://blog.csdn.net/feizhixuan46789/article/details/9252887 学习开发一个有效的途径就是借鉴成熟的案例作为学习的对象&#xff0c;下面为大家推荐一些比较不错的Android项目&#xff0c;有些也是在其它的帖子中发现的&#xff0c;欢迎大家补充&#…

Boost智能指针——weak_ptr .

http://blog.csdn.net/afrish/article/details/3985636 【通知】关于近期用户博文被恶意投票的解决办法 bShare分享&#xff0c;迅速提升10倍流量 Boost智能指针——weak_ptr 分类&#xff1a; BOOST 2009-03-12 22:58 815人阅读 评论(1) 收藏 举报 Boost智能指针—…

MongoDB中的 Limit和Skip方法实现分页,Sort实现排序,Count实现统计个数,distinct去除重复数据(八)

MongoDB也有Limit读取指定数量的数据记录&#xff0c;Skip 跳过指定数量的数据&#xff0c;它俩结合起来就可以做一个分页 Sort是MongoDB内置的排序方法&#xff0c;和上面的Limit&#xff0c;Skip可以合用 准备测试数据 > db.col.find() { "_id" : ObjectId(&qu…

利用office2000组件进行填充打印报不支持集合。 (Exception from HRESULT: 0x80020011 (DISP_E_NOTACOLLECTION))...

环境&#xff1a;win2008 64位.net4.0 office2000 错误提示&#xff1a; 不支持集合。 (Exception from HRESULT: 0x80020011 (DISP_E_NOTACOLLECTION)) at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWra…

《我的泛型编程观》之boost.scoped_ptr、scoped_array源码分析

http://hi.baidu.com/_%E2d_%B7%B3_%DE%B2%C2%D2/blog/item/1d7739d92055bb2610df9b5c.html 《我的泛型编程观》之boost.scoped_ptr、scoped_array源码分析 2009年12月06日 星期日 下午 06:57boost.scoped_ptr已经被tr2建议作为C标准库的一部分&#xff0c;它的兄弟shared_ptr已…

Qt内建对话框简介

http://www.iteye.com/topic/711655 1.QErrorMessage 错误信息对话框 QErrorMessage提供了一个错误信息显示的对话框。 一个错误信息部件由一个文本域和一个复选框组成。复选框让用户控制是否下一次还显示这个错误信息&#xff0c;通常显示的文本为“Show this message again…

MongoDB聚合(管道) 九

MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等)&#xff0c;并返回计算后的数据结果。有点类似sql语句中的 count(*)。 语法&#xff1a; db.collection.aggregate(AGGREGATE_OPERATION) //AGGREGATE_OPERATION是下面的表中的聚合表达式和管道结合的产物下…