Chinaunix首页 | 论坛 | 博客
  • 博客访问: 713563
  • 博文数量: 102
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1748
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-23 15:42
个人简介

寻找严肃、沉默和专注的力量。

文章分类

全部博文(102)

文章存档

2015年(26)

2014年(8)

2013年(68)

分类: C/C++

2013-07-11 17:57:15

    计算机系统中资源有很多种,内存是我们最常用到的,此外还有文件描述符、socket、操作系统handle、数据库连接等资源,程序中申请这些资源后需要及时归还系统,否则可能产生不可预知的后果。
   管理内存等资源时,RAII机制很适合在栈上创建的对象,离开作用域对象自动销毁从而调用析构函数释放资源。但如果对象是new操作符在堆上创建的,那么它的析构函数不会自动调用,程序员必须明确地应用delete操作符销毁它才能释放资源。这就存在着安全隐患,如果因某些意外导致程序未能执行delete,那么内存等资源就永久地丢失了。如下所示
   int *p = new class_need_resource;
   ...                                                        //可能发生异常导致资源泄露
   delete p;
new、delete以及指针的不恰当运用是C++中造成资源获取、释放问题的根源,智能指针是解决这一问题的一个好的选择。
   C++标准库中提供std::auto_ptr参考http://blog.chinaunix.net/uid-26722078-id-3795959.html,部分地解决了获取资源自动释放的问题,但是仍有一些缺陷,boost.smart_ptr库是一个好的补充,包括scoped_ptr、scoped_array、shared_ptr、shared_array、weak_ptr和intrusive_ptr等6种智能指针。它们都是轻量级的对象,速度与原始指针相差无几,对于所指的类型T也仅有一个很小且合理的需求:析构函数不能抛出异常。

scoped_ptr和scoped_array
   
scoped_ptr类似auto_ptr,包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确删除。但scoped_ptr的所有权不能更改,一旦scoped_ptr获取对象的管理权,你就无法从它那里取回来(顾名思义,只能在本地作用域里使用,不希望被转让)。
   scoped_ptr类摘要及注释说明

点击(此处)折叠或打开

  1. template<class T>
  2. class scoped_ptr {
  3. private:
  4.     T * px;
  5.     scoped_ptr(scoped_ptr const &);                      //禁止拷贝
  6.     scoped_ptr & operator=(scoped_ptr const &);          //禁止赋值   禁止拷贝、赋值保证了被它管理的指针不能转让所有权
  7. public:
  8.     explicit scoped_ptr(T* p = 0);
  9.     ~scoped_ptr();

  10.     void reset(T * p = 0);                               //置空
  11.     T & operator*() const;                               //实现指针*
  12.     T * operator->() const;                              //实现指针->
  13.     T * get() const;                                     //返回内部保存的原始指针
  14.    
  15.     void swap(scoped_ptr &b);                            //交换保存的原始指针
  16. }

用法很简单
scoped_ptr p(new int);
scoped_ptr sp(new string("text"));
scoped_ptr sp(new Example());
然后可以像普通指针一样使用这些scoped_ptr
注意:++等操作符未定义,拷贝构造不支持
sp++;          //错误
scoped_ptr sp2 = sp;  //错误 
与auto_ptr的区别

大多数情况可以与auto_ptr互换,或者从auto_ptr获得指针管理权(同时auto_ptr失去管理权),因为不支持拷贝和赋值,不能用作容器的元素

scoped_array
scoped_array类似scoped_ptr,包装了new[],接口和功能几乎与scoped_ptr一样,创建方式如下所示:
scoped_array sa(new int[100]);
重载[]操作符后用起来就像使用数组,同样不提供数组索引范围检查,但是不提供数组首地址+N的用法,如下所示:
*(sa+1)=20;//错误用法,编译会报错
一般不推荐使用scoped_array,需要动态数组使用std::vector通常能更好的的解决问题。
阅读(1156) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~