《Effective C++》学习笔记条款13 以对象管理资源
例:
voidf()
{
Investment *pInv = createInvestment();
... //这里存在诸多“不定因素”,可能造成delete pInv;得不到执行,这可能就存在潜在的内存泄露。
delete pInv;
}
解决方法:把资源放进对象内,我们便可依赖C++的“析构函数自动调用机制”确保资源被释放。
许多资源被动态分配于堆内而后被用于单一区块或函数内。它们应该在控制流离开那个区块或函数时被释放。标准
程序库提供的auto_ptr正是针对这种形势而设计的特制产品。auto_ptr是个“类指针对象”,也就是所谓的“智能指针”,
其析构函数自动对其所指对象调用delete。
void f()
{
std::auto_ptr<Investment> pInv(createInvestment());
...
} //函数退出,auto_ptr调用析构函数自动调用delete,删除pInv;无需显示调用delete。
“以对象管理资源”的两个关键想法:
- 获得资源后立刻放进管理对象内(如auto_ptr)。每一笔资源都在获得的同时立刻被放进管理对象中。“资源取得时机便是初始化时机”(Resource Acquisition Is Initialization;RAII)。
- 管理对象运用析构函数确保资源被释放。即一旦对象被销毁,其析构函数被自动调用来释放资源。
由于auto_ptr被销毁时会自动删除它所指之物,所以不能让多个auto_ptr同时指向同一对象。所以auto_ptr若通
过copying函数复制它们,它们会变成NULL,而复制所得的指针将取得资源的唯一拥有权!
看下面例子:
std::auto_ptr<Investment> pInv1(createInvestment()); //pInv1指向createInvestment()返回物;
std::auto_ptr<Investment>pInv2(pInv1); //现在pInv2指向对象,而pInv1被设为NULL;
pInv1 = pInv2; //现在pInv1指向对象,而pIn2被设为NULL;
受auto_ptr管理的资源必须绝对没有一个以上的auto_ptr同时指向它。即“有你没我,有我没你”。
auto_ptr的替代方案是“引用计数型智能指针”(reference-counting smart pointer;SCSP)、它可以持续跟踪共有
多少对象指向某笔资源,并在无人指向它时自动删除该资源。
TR1的tr1::shared_ptr就是一个"引用计数型智能指针"。
void f()
{
...
std::tr1::shared_ptr<Investment> pInv1(createInvestment()); //pInv1指向createInvestment()返回物;
std::tr1::shared_ptr<Investment> pInv2(pInv1); //pInv1,pInv2指向同一个对象;
pInv1 = pInv2; //同上,无变化
...
} //函数退出,pInv1,pInv2被销毁,它们所指的对象也竟被自动释放。
auto_ptr和tr1::shared_ptr都在其析构函数内做delete而不是delete[],也就意味着在动态分配而得的数组身上使
用auto_ptr或tr1::shared_ptr是个潜在危险,资源得不到释放。也许boost::scoped_array和boost::shared_array能提供
帮助。还有,vector和string几乎总是可以取代动态分配而得的数组。
请记住:
- 为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源。
- 两个常被使用的RAII类分别是auto_ptr和tr1::shared_ptr。后者通常是较佳选择,因为其拷贝行为比较直观。若选择auto_ptr,复制动作会使他(被复制物)指向NULL。
最新文章
- javascript之小积累-匿名函数表达式的最佳实践
- 判断scrollview是否滚动到了底部
- VisualSVN Server的配置和使用方法 图文
- 排队打饭 sdut 2443【最简单的贪心法应用举例】
- textViewDidChange: crashes in iOS 7
- python os.path 模块
- .net MVC全局定时器执行作业
- Windows下MySQL数据库备份脚本(二)
- block 做参数
- bzoj1003[ZJOI2006]物流运输trans
- matlab 中max函数用法
- 51Nod 1284 2 3 5 7的倍数 容斥原理
- cookie/session(过时的写法)
- 欢迎进入我的个人博客 anzhan.me
- java学习——递归
- 【学习总结】Git学习-参考廖雪峰老师教程八-使用GitHub
- 建立Oracle GoldenGate凭证
- 玩转X-CTR100 l STM32F4 l MPU6050加速度陀螺仪传感器
- Monitor Minio server with Prometheus
- NopCommerce 执行计划任务不同Services协调操作导致更新数据失败的问题!
热门文章
- 读《CSCW的一种建模与实现方法》
- wpf RadioButton控件的一个bug,onpropertychanged后会修改旧属性的值
- 解决Android SDK Manager更新(一个更新Host的程序的原理实现和源码)
- uva 1396 - Most Distant Point from the Sea
- MDN >; Web technology for developers >; HTTP
- HTML5 Geolocation
- Linq 筛选出一条数据
- POJ_1220_Nmber Sequence
- 搭建Eclipse C/C++开发环境
- 产品设计中先熟练使用铅笔 不要依赖Axure