代码改变世界

Boost学习笔记----SmartPointer之Boost::scoped_ptr

2009-12-10 22:28  libiver  阅读(263)  评论(0编辑  收藏  举报

声明:欢迎任何人和组织转载本blog中文章,但必须标记文章原始链接和作者信息。  

本文链接:http://blog.csdn.net/li_007/archive/2009/12/11/4982419.aspx .aspx">

开拓进取的小乌龟------->CSDN点滴点点滴滴Blog

    很久之前就看了一些Boost的介绍,也一直在断断续续地关注着它,可就是没有去学习下或者写段代码来验证下。终于在一年到底的时候,静下来买回来《Beyond The C++ Standard Library--An Introduction to Boost》这本大作,安静地看看Boost的真面目,也亲身体会下Boost的安全性,高效,实用(当然是相比较STL而言拉)。

    很简单的一段代码吧,可是在这里我只是对p进行了一次赋值,如果我进行了很多次赋值,100次,甚至更多,其实这在一个项目中是很有可能。这个时候我们怎么去delete来释放stack,很容易让我们多次delete而引发exception。或者最后很多人自己都糊涂了,根本就不知道自己到底释放了没有,并且不合时宜的delete更会引发exception。当然解决办法就已使用引用计数。

 

    好了言归正传,来说说Boost::scoped_ptr这个Smart Pointer。其实在STL中也有智能指针,std::auto_ptr,它可以解决我们delete的问题,可以自动帮助我们释放stack,特别是在异常的时候,可以帮助我们正确释放stack。但是std::auto_ptr也有自己缺点,比如它对其他的stl的支持不好(大部分时候编译都通不过的)。boost中的智能指针就是为了弥补等等这些缺点而设计的,在boost中有scoped_ptr、scoped_array、shared_ptr和shared_array这四个智能指针,后面的学习笔记中会慢慢介绍。

   scoped_ptr是一个轻量级的smart pointer实现,它拥有着和auto_ptr类似的功能,都是为了正确地帮助我们释放动态分配的对象,但是它也和auto_ptr有着很大的区别。scoped_ptr假定它对它指向的对象拥有所有权,并且在任何时候都不会意外放弃所有权。既然如此,scoped_ptr就肯定不可能进行赋值或者被复制了,但是auto_ptr是可以做这些操作的,所以在真正的应用上我们要根据实际来选择(但是我觉得可以基本放弃stl的auto_ptr了)。看看scoped_ptr的定义,如下:

 

   发现了一个规律就是所有实现都不抛出异常。特别是*和->操作符的重载,使得我们可以像使用普通的指针一样简单方便,由于scoped_ptr是轻量级的,所以它不会增加代码,也不会使Application运行变慢,它会让我们的code更健壮,更易于维护。

   reset成员函数的作用是重置scoped_ptr,也即是删除scoped_ptr所存储的指针,然后保存p。在实际的应用中我们应该尽量少用这个函数或者不用。

   get成员函数的作用是返回它所存储的指针,我们同样应该少用这个函数,多使用scoped_ptr为我们重载的操作符。get函数可以让我们操作裸指针,这是危险的。

   在上面的example中,我们看到scoped_ptr的使用像普通指针一样,没有什么区别。而且是不可以复制或者赋值的,但是auto_ptr就不同了,它可以通过赋值来构造也可以通过复制来赋值的。但是在上面的赋值之后,autoPointer就只剩下一个空指针。

 

  再次强调我们要少用get函数,比如在上面的example中,bsPointer在调用了get函数后,会得到一个裸指针,它指向了“Use scoped_ptr often.”内存块。如果我们不小心释放了这个裸指针,在scoped_ptr自己再次释放的时候会出现错误,同样不要把它再次赋值给另外的scoped_ptr,这样也会产生多次释放的错误。

 

   最后结合平时编程遇到的问题,总结哈这个智能指针的使用:

   1、在有可能抛出异常的作用域中。

   2、函数中存在多条控制路径时

   3、动态分配的对象的生命周期可以限定在一个特定的作用域范围内时

   4、考虑异常安全的时候

 

  PS:其实我希望有可能尽量少用或者不用auto_ptr(c++ox标准委员会已经接纳了boost的smart pointer)。