effective C++ 读书笔记(三)

来源:互联网 发布:淘宝 代写小说大纲 编辑:程序博客网 时间:2024/06/11 03:46

第三章资源管理

条款13:以对象管理资源

RAAI(Resource Acquisition IsInitialization: RAII) 资源取得时机便是初始化时机

n        为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源

n        两个常被使用的RAIIclasses分别是tr1::shared_ptr和auto_ptr。前者通常是较佳选择,因为其copy行为比较直观。若选择auto_ptr,复制动作会使它(被复制物)指向null。

auto_ptr:

auto_ptr在构造时获取对某个对象的所有权,在析构时释放该对象。其析构函数自动对其所指对象调用delete

 int*p = new int(0);

 auto_ptr<int>ap(p);

auto_ptr<nt> ap(new int(0)); //获得资源后立刻放进管理对象RAAI

从此我们不必关心何时释放p,也不用担心发生异常会有内存泄漏。

要记住几点:

1. auto_ptr析构的时候肯定会删除他所拥有的那个对象,所以两个auto_ptr不能同时拥有同一个对象。为了预防这个问题,auto_ptr有个性质:若通过copy构造函数或copy assignment操作符复制它们,它们会变成null,而复制所得的指针将取得资源的唯一拥有权。

2. auto_ptr的析构函数中删除指针用的是delete,而不是delete[],所以我们不该用auto_ptr来管理一个数组指针。

shared_ptr: 一种“已用计数型智慧指针(RCSP Reference-counting smart pointer)”

RCSP持续追踪共有多少对象指向某笔资源,并在无人指向它时自动删除该资源。但它无法打破环状引用,例如两个其实已经没被使用的对象彼此互指,因而好像还处在“被使用”状态。

 

条款14:在资源管理类中小心copying行为

n        复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为

n        普通而常见的RAII classcopying行为是:抑制copying 、施行引用计数法。

tr1::shared_ptr允许指定所谓的“删除器”

 

条款15:在资源管理类中提供对原始资源的访问

n        APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理之资源”的办法

n        对原始资源的访问可能经由显示转换或隐式转换。一般而言显式转换比较安全,但隐式转换对客户比较方便。

 

条款16:成对使用new和delete时要采取相同形式

n        如果你在new表达式中使用[],必须在相应的delete表达式中也使用[]。如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[]

 

条款17:以独立语句将newed对象置入智能指针

n        以独立语句将newed对象置入智能指针内。如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。

例如

int priority();

voidprocessWidged(std::tr1::shared_ptr<Widget> pw, int priority);

考虑调用

processWidged(std::tr1::shared_ptr<Widget>(newWidget), priority())

可能会产生这样的执行顺序:

1. 执行new Widget

2. 调用priority

3. 调用tr1::shared_ptr构造函数

如果priority的调用导致异常,new Widget返回的指针将会遗失,所以应该采用以下的调用方法:

std::tr1::shared_ptr<Widget> pw(newWidget);

processWidget(pw, priority());