C++内存管理------>以对象管理资源(Effective C++)
来源:互联网 发布:电子商务网络推广 编辑:程序博客网 时间:2024/06/05 17:02
考虑如下一个类:
class Investment{...};
进一步假设,这个程序库通过一个工厂函数供应我们特定的Investment对象:
Investment* createInvestment();//返回指针,指向Investment继承体系内的动态分配对象。调用者有责任删除它。
现在考虑有个 f 函数履行了这个职责:
void f(){ Investment* pInv=createInvestment();//调用工厂函数 ... delete pInv;//释放pInv所指对象}
这看起来妥当。但若干情况下 f 可能无法删除它得createInvestment的投资对象。或许因为“….”区域内的一个过早的return语句。如果这样的return 语句被执行起来,控制流就绝不会触及delete语句类似情况发生在对createInvestment的使用及delete动作位于某循环内,而该循环由于某个continue或者go语句过早退出。最后一种可能是“…..”区域内的语句抛出异常,果真如此控制流将再次不会临delete。无论delete如何被略过去,我们泄露的不只是内含投资对象的那块内存,还包括那些投资对象所保存的任何资源。
为确保createInvestment返回的资源总是被释放,我们需要将资源放进对象内,当控制流离开f,该对象的析构函数会自动释放那些资源。即:把资源放进对象内,我们便可倚赖C++的“析构函数自动调用机制”确保资源被释放。
许多资源被动态分配于heap内而被用于单一区块或函数内。它们应该在控制流离开那个区块或函数时被释放。标准程序库提供的auto_ptr正是针对这种形式而设计的特制产品。auto_ptr是个“类指针对象”。也就是所谓的“智能指针”,其析构函数自动对其所指对象调用delete。下面示范如何使用auto_ptr以避免f函数潜在的资源泄露可能性:
void f(){ std::auto_ptr<Investment> pInv(createInvestment()); //调用工厂函数 //继续使用pInv //经由auto_ptr的析构函数自动删除pInv ...}
以对象管理资源的两个关键想法:
一、获得资源后立刻放进管理对象
二、管理对象运用析构函数确保资源被释放
由于auto_ptr被销毁时会自动删除它所指之物,所以一定注意别让多个auto_ptr同时指向同一对象。如果真是那样,对象会被删除一次以上,而那会使你的程序搭上驶向“未定义行为”的快速列车上。为了预防这个问题,auto_ptr有一个不寻常的性质:若通过copy构造函数或copy assignment操作符控制它们,它们会变成NULL,而复制所得的指针将取得资源的唯一拥有权。
std::auto_ptr<Investment> pInv1(createInvestment());//pInv1指向createInvestment返回物 std::auto_ptr<Investment> pInv2(pInv1);//现在pInv2指向对象,pInv1被设为NULL pInv1=pInv2;//现在pInv1指向对象,pInv2被设为NULL
由此可见auto_ptr并非管理动态分配资源的神兵利器。举个例子,STL容器要求其元素发挥正常的复制行为,因此这些容器容不得auto_ptr
auto_ptr的替代方案是“引用计数型智慧指针(RCSP)”。所谓的RCSP也是个智能指针,持续追踪共有多少对象指向某笔资源,并在无人指向它时自动删除。RCSP提供的行为类似垃圾回收,不同的是RCSP无法打破环状引用(例如两个其实已经没被使用的对象彼此互指,因而好像还处在“被使用状态”)
TR1的tr1::shared_ptr就是个RCSP,所以你可以这么写f:
void f(){ ... std::tr1::shared_ptr<Investment> pInv(createInvestment()); //调用工厂函数 //使用pInv一如以往 ...}//经由shared_ptr析构函数自动删除pInv
这段代码与auto_ptr那个版本相同,但是shared_ptr的复制行为正常多了。
void f(){ ... std::tr1::shared_ptr<Investment> pInv1(createInvestment());//pInv1指向createInvestment返回物 std::tr1::shared_ptr<Investment> pInv2(pInv1);//pInv2和pInv1指向同一个对象 pInv1=pInv2;//同上,无任何改变 ...}//pInv2和pInv1被销毁,它们所指的对象也就被自动销毁
auto_ptr和tr1::shared_ptr两者都在其析构函数内做delete而不是delete[ ]动作。那意味着在动态分配而得的array身上使用auto_ptr或tr1::shared_ptr是个馊主意。尽管如此,这么做仍然能通过编译!
std::auto_ptr1<std::string> aps(new std::string[10]);//这么做是错的,会用上错误的delete形式std::tr1::shared_ptr<int> spi(new int[1024]);//同上
- C++内存管理------>以对象管理资源(Effective C++)
- 【Effective c++】条款13:以对象管理资源
- 《Effective C++》学习笔记条款13 以对象管理资源
- Effective C++——》条款13:以对象管理资源
- Effective C++:条款13:以对象管理资源
- 读书笔记《Effective C++》条款13:以对象管理资源
- <Effective C++> (Item 13-15): 以对象管理资源
- 【C++】动态内存管理(二)以对象管理资源
- Effective C++(13) 用对象管理资源
- C++中以对象管理资源<auto_ptr>(13)---《Effective C++》
- Effective C++ ----以对象管理资源
- Effective C++读后感:以对象管理资源
- effective c++ 以对象管理资源
- 《Effect C++》学习------条款13:以对象管理资源
- [C++]以对象管理指针
- Effective C++ 条款13学习笔记:以对象管理资源
- Effective C++ 学记之13 以对象管理资源
- Effective C++ 条款13 以对象管理资源
- 笔试小技巧--隔板法解排列组合问题(附代码)
- Android中ExpandableListView的使用(一)
- 从程序员到项目经理(8):程序员加油站 -- 不要死于直率
- JSP 中 如何使用 spring:message 标签
- ceph format1格式image
- C++内存管理------>以对象管理资源(Effective C++)
- Android---广播(Broadcast)---广播接收者的注册过程分析
- linux四种查找命令的方法
- 利用 Chrome 开发者工具远程调试 Android 中的原生 WebView
- python中的爬虫神器 XPath 介绍
- 常用基础命令
- web开发中spring集成shiro进行权限管理
- 将下载到本地的JAR包手动添加到Maven仓库
- Neutron的介绍