如果我们使用一个投资行为的程序库:

#include "stdafx.h"
#include <iostream>
#include <memory>
using namespace std;
class Investment
{
public:
};
class InvestmentFactory
{
public:
virtual Investment* createInvestment()
{
Investment * inV = NULL;
return inV;
}
};
//第一版,这里可能发生内存泄露,比方在调用createInvestmen()之后到delete pInv之间的函数体之间发生了异常或者调用了return等
//那么delete语句将不会被运行,早成内存泄露
void f()
{
InvestmentFactory fac;
Investment* pInv = fac.createInvestment(); delete pInv;
} int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}

//第一版,这里可能发生内存泄露,比方在调用createInvestmen()之后到delete pInv之间的函数体之间发生了异常或者调用了return等

//那么delete语句将不会被运行,早成内存泄露

<span style="color:#3333ff;">void f()
{
InvestmentFactory fac;
Investment* pInv = fac.createInvestment(); delete pInv;
}</span>

//第二版:为了确保createInvestment返回的资源总是被释放,我们须要将资源放进对象内。当控制流离开f,该对象的析构函数会自己主动释放那些资源

//auto_ptr是个类指针对象,也就是所谓的“智能指针”。其析构函数会自己主动对其所指对象调用delete。

<span style="color:#3333ff;">void f()
{
InvestmentFactory fac;
std::auto_ptr<Investment> pInv(fac.createInvestment());//调用factory函数,一如既往的使用pInv。经由auto_ptr的析构函数自己主动删除pInv
}</span>

//上面第二版“以对象管理资源”的两个关键想法



1:获得资源后马上放进管理对象:以上代码createInvestmen返回的资源被当做其管理者auto_ptr的初值。

对象资源管理的观念也被称为

资源取得实际便是初始化时机。由于我们总是在获得一笔资源后于允许语句内以它初始化某个管理对象

2:管理对象运用析构函数确保资源被释放

//第二版存在的问题:

//因为auto_ptr被销毁时会自己主动删除它所指之物,所以一定要注意别让多个auto_ptr同一时候指向某一对象。假设真是这样。对象会被删除一次以上,程序

//出现没有定义行为,为了防止这个问题,auto_ptr有一个不平常的性质:若通过copy构造函数或者copy assigment操作符复制他们,他们会变为null

//而复制所得的指针将取得资源的唯一全部权。

auto_ptr<Investmen> pInv1(fac.createInvestment()); pInv1指向资源

auto_ptr<Investment> pInv2(pInv1); pInv2指向资源pInv1为NULL

pInv1 = pInv2; pInv1指向对象,pInv2成为null



//第三版:

<span style="color:#3333ff;">void f()
{
InvestmentFactory fac;
std::shared_ptr<Investment> pInv1(fac.createInvestment());//调用factory函数。一如既往的使用pInv,经由shared_ptr的析构函数自己主动删除pInv tr1::shared_ptr<Investment> pInv2(pInv1);//pInv1 和 pInv2 指向一个资源对象
pInv2 = pInv1;//同上,无不论什么改变 //当pInv1 and pInv2 销毁的时候,它们所指的对象也被自己主动销毁
}</span>

/*

第三版能够正常使用,也是最佳版本号。 可是注意auto_ptr and shared_ptr在析构函数其中都是做的 delete而不是delete[],所以不要把

动态分配而得的array用在auto_ptr and shared_ptr身上。

*/

总结:

为防止资源泄露,请使用对象管理资源,他们在构造函数其中获得资源。并在析构函数其中释放资源

两个经常使用的RAII class 为 tr1::shared_ptr and auto_ptr;第一个是最佳选择由于其copy行为比較直观,若选择auto_ptr复制动作会使得它指向null。

effective C++ 读书笔记 条款14 以对象管理资源的更多相关文章

  1. 《Effective C++》学习笔记条款13 以对象管理资源

    条款 13 :以对象管理资源 例:      voidf()      {           Investment *pInv = createInvestment();           ... ...

  2. Effective C++ 条款13/14 以对象管理资源 || 在资源管理类中小心拷贝行为

    三.资源管理       资源就是一旦你使用了它,将来不用的时候必须归还系统.C++中最常用的资源就是动态内存分配.其实,资源还有 文件描述符.互斥器.图形界面中的字形.画刷.数据库连接.socket ...

  3. effective C++ 读书笔记 条款08

    条款08  别让异常逃离析构函数: 假设在析构函数其中发生了异常,程序可能会过早结束或者导致不明白行为(异常从析构函数传播出去) 看代码: #include <iostream> usin ...

  4. effective C++ 读书笔记 条款11

    条款11: 在operator= 中处理"自我赋值" 在实现operator=时考虑自我赋值是必要的就像 x=y .我们不知道变量x与y代表的值是否为同一个值(把x和y说成是一个指 ...

  5. Effective Java2读书笔记-创建和销毁对象(三)

    第5条:避免创建不必要的对象 本条主要讲的是一些反面教材,希望大家引以为鉴. ①无意中使用自动装箱导致多创建对象. public class Sum { public static void main ...

  6. Effective Java2读书笔记-创建和销毁对象(一)

    第1条:考虑用静态工厂方法代替构造器 通常情况下,我们创建一个对象采取new的形式,但是还有一种方法也是经常使用到的,它的名称叫做静态工厂方法. 例如,java中基本类型boolean的包装类Bool ...

  7. Effective Java读书笔记--创建和销毁对象

    1.优先考虑用静态工厂方法代替构造器2.遇到多个构造器参数时要考虑使用构建器Builder解决参数过多,不可变类型.私有构造方法,静态类的构造方法提供必要参数,剩下可选.new xxx.build() ...

  8. Effective Java2读书笔记-创建和销毁对象(四)

    第7条:避免使用终结方法 这一条讲的简直是不知所云.先简单记下来其中说出的几条: ①显式终止方法的典型例子有InputStream.OutputStream和java.sql.Connection上的 ...

  9. Effective Java2读书笔记-创建和销毁对象(二)

    第3条:用私有构造器或者枚举类型强化Singleton属性 这一条,总体来说,就是讲了一个小技巧,将构造器声明为private,可以实现单例.具体有以下几种实现的方式. ①最传统的单例实现模式,可能有 ...

随机推荐

  1. 清除浮动(float)的影响

    浮动会导致父元素塌陷如图: 解决办法: 父元素overflow:hidden,如图 末尾插入子元素clear,如图 为甚么,父元素overflow:hidden会解决塌陷问题? 来自知乎貘吃馍香的回答 ...

  2. binlog_format不同模式下,对mysqlbinlog恢复的影响

      binlog_format='mixed' (root)[(none)]>use test; Reading table information for completion of tabl ...

  3. Xilinx FPGA编程技巧之常用时序约束详解

    1.   基本的约束方法 为了保证成功的设计,所有路径的时序要求必须能够让执行工具获取.最普遍的三种路径为: 输入路径(Input Path),使用输入约束 寄存器到寄存器路径(Register-to ...

  4. 十年后我不会log,还是活的很好啊

    混迹于互联网也一两年了,出于喜爱与生活压力依然会从事很久.迟迟不写博客,大概是觉得知识与经验积累在笔记上时不时看看就好了,而实际情况是笔记很少翻,遇到问题搜博客和百度依然是首选,故开通博客记录自己工作 ...

  5. 扩增子分析QIIME2-2数据导入Importing data

    # 激活工作环境 source activate qiime2-2017.8 # 建立工作目录 mkdir -p qiime2-importing-tutorial cd qiime2-importi ...

  6. jmeter元件的作用域和顺序

    jmeter是一个开源的性能测试工具,它可以通过鼠标拖拽来随意改变元件之间的顺序以及元件的父子关系,那么随着它们的顺序和所在的域不同,它们在执行的时候,也会有很多不同. jmeter的test pla ...

  7. iptables详解(1):iptables概念

    所属分类:IPtables  Linux基础  基础知识  常用命令 这篇文章会尽量以通俗易懂的方式描述iptables的相关概念,请耐心的读完它. 防火墙相关概念 此处先描述一些相关概念. 从逻辑上 ...

  8. 「 COGS 1669 」 神秘的咒语

    题目大意 这出题人太凉心,居然给我句鸟语.(连我最爱的OI也被鸟语污染了吗) 下面给大家说说这句鸟语啥意思.不要误会,都是度娘的功劳 QAQ 之前不是给出了两个伪咒语吗. 这句鸟语就是说真正的咒语就是 ...

  9. Python学习第二阶段day1 内置函数,序列化,软件目录开发规范

    内置函数 1.abs()  求绝对值 2.all()    所有元素为真才返回真 all( [1,1,2,3,-1] ) 值为True 3.any()   所有元素为假才返回假  any([0,0,0 ...

  10. python之cookbook-day01

    第一章:数据结构和算法 1.1 解压序列赋值给多个变量 >>> p = (4, 5) >>> x, y = p >>> x 4 >>& ...