使用智能指针管理对象资源
2014-09-15 13:20
218 查看
前言
在前面的文章中,细致地分析了构造函数,拷贝构造函数,赋值运算符,析构函数这几个类中最重要函数的用法。
如果严格地遵循这些做法,可以消除绝大部分资源管理的问题。
然而,要想更灵活的使用对象中的资源,仅仅这些还不够。譬如,若你想自己控制对象资源的生命周期(不要在作用域结束的时候自动被析构掉),那就应当好好考虑下智能指针了。
有人说,智能指针是属于设计模式范畴的产物,这么说有点偏激,但也确实有点道理。
问题分析
我们假定有一个投资类Investment:
很多其他的投资类型都由这个类派生出来,比如股票投资,基金投资等等。
进一步假设,有某个工厂函数专门供应特定的Investment对象:
必须说明的是,这个函数是通过new来在堆中创建对象的,因此,函数结束后,资源并不会释放掉,而是需要调用这个函数的用户来手工释放掉,如下所示:
下面问题来了:如果在 4 - 6行之间有 continue 或者 goto 或者其他中断程序执行的语句,那么将会导致 delete 无法运行,从而内存泄露。
这种情况下,用户肯定是想 pInv 在作用域结束的时候就会自动地释放掉,好在智能指针能解决这个问题。
智能指针介绍
智能指针的本质其实是一个能够帮用户管理资源的类指针对象。
许多资源被动态分配于heap后被用于单一区块或函数内,智能指针可以让资源在离开控制流的时候得到释放。
应用得比较多的有auto_ptr和shared_ptr两种智能指针。
前者管理的资源必须是一个智能指针所指向的。当前者进行赋值的时候,会将赋值运算符右值的智能指针变成NULL,而其左值获得右边指针原来指向的资源。
后者管理的资源则未必,它允许多个智能指针指向同一份资源,同时会统计资源被指的个数,只有指向该资源的智能指针都离开了作用域,才会正式析构掉资源。
智能指针的使用:
在构造好了智能指针之后,便可以不用理会该资源回收的事,智能指针将会帮你打理!
如果要通过智能指针获得原始资源指针,则调用智能指针的 .get() 即可,而如果要访问原始资源,智能指针重载了->和*()操作符,使用起来和原始指针一样。
另外,智能指针shared_ptr还可以自定义删除器,指定删除对象时(指向资源的指针数为0)要做的具体事情(不一定是销毁资源)。
由于智能指针的类型很多,使用方法也五花八门,这里就不一一介绍了,请参考相关的使用手册。
小结
1. 当你需要提前实现多态的话,请new一个子类并将结果返回给一个父类指针。
2. 智能指针不支持内置类型,那是因为C++认为Vector可以完全取代动态分配而得到的数组。
在前面的文章中,细致地分析了构造函数,拷贝构造函数,赋值运算符,析构函数这几个类中最重要函数的用法。
如果严格地遵循这些做法,可以消除绝大部分资源管理的问题。
然而,要想更灵活的使用对象中的资源,仅仅这些还不够。譬如,若你想自己控制对象资源的生命周期(不要在作用域结束的时候自动被析构掉),那就应当好好考虑下智能指针了。
有人说,智能指针是属于设计模式范畴的产物,这么说有点偏激,但也确实有点道理。
问题分析
我们假定有一个投资类Investment:
class Investment { // ...... };
很多其他的投资类型都由这个类派生出来,比如股票投资,基金投资等等。
进一步假设,有某个工厂函数专门供应特定的Investment对象:
Investment * createInvestment();
必须说明的是,这个函数是通过new来在堆中创建对象的,因此,函数结束后,资源并不会释放掉,而是需要调用这个函数的用户来手工释放掉,如下所示:
void f() { // ...... Investment * pInv = createInvestment(); // ...... delete pInv; // ...... }
下面问题来了:如果在 4 - 6行之间有 continue 或者 goto 或者其他中断程序执行的语句,那么将会导致 delete 无法运行,从而内存泄露。
这种情况下,用户肯定是想 pInv 在作用域结束的时候就会自动地释放掉,好在智能指针能解决这个问题。
智能指针介绍
智能指针的本质其实是一个能够帮用户管理资源的类指针对象。
许多资源被动态分配于heap后被用于单一区块或函数内,智能指针可以让资源在离开控制流的时候得到释放。
应用得比较多的有auto_ptr和shared_ptr两种智能指针。
前者管理的资源必须是一个智能指针所指向的。当前者进行赋值的时候,会将赋值运算符右值的智能指针变成NULL,而其左值获得右边指针原来指向的资源。
后者管理的资源则未必,它允许多个智能指针指向同一份资源,同时会统计资源被指的个数,只有指向该资源的智能指针都离开了作用域,才会正式析构掉资源。
智能指针的使用:
void f() { // ...... std::auto_ptr<Investment>pInv(createInvestment()); std::shared_ptr<Investment>pInv(createInvestment()); // ...... }
在构造好了智能指针之后,便可以不用理会该资源回收的事,智能指针将会帮你打理!
如果要通过智能指针获得原始资源指针,则调用智能指针的 .get() 即可,而如果要访问原始资源,智能指针重载了->和*()操作符,使用起来和原始指针一样。
另外,智能指针shared_ptr还可以自定义删除器,指定删除对象时(指向资源的指针数为0)要做的具体事情(不一定是销毁资源)。
由于智能指针的类型很多,使用方法也五花八门,这里就不一一介绍了,请参考相关的使用手册。
小结
1. 当你需要提前实现多态的话,请new一个子类并将结果返回给一个父类指针。
2. 智能指针不支持内置类型,那是因为C++认为Vector可以完全取代动态分配而得到的数组。
相关文章推荐
- 第十一章:使用智能指针管理对象资源
- C++箴言<13>:使用对象管理资源
- effective c++ 条款13,16(以对象管理资源,成对使用new delete的形式相同)
- 自动资源释放-使用对象管理资源,解决资源泄露问题
- 以对象管理资源----智能指针
- 使用RAII来管理对象资源
- 使用对象来管理资源
- 使用对象管理资源
- 【C++箴言:使用对象管理资源】
- Item 13:使用对象(智能指针)来管理资源 Effective C++笔记
- effective c++ item13:使用对象管理资源
- 使用对象来管理资源
- C++编程规范之13:确保资源为对象所拥有。使用显示的RAII和智能指针
- C++箴言:使用对象管理资源
- GDI对象的使用和防止资源泄露
- Item3:Use objects to manage resources--以对象管理资源
- 使用 Exchange 命令行管理程序设置对资源邮箱日程的完全访问权
- C#中使用SQL Server分布式管理对象(SQL-DMO)
- 第 5 章 使用数据库管理资源
- Response对象——使用Cookies对象管理状态