《Effective C++》第三章:资源管理

来源:互联网 发布:iphone游戏推荐 知乎 编辑:程序博客网 时间:2024/05/22 09:39

条款13:以对象管理资源

主要的思想是C++的“析构函数自动调用机制”,即栈上的变量会在离开作用域后自动调用析构函数。但是对于heap上的变量,编译器不会自动调用析构函数,通常需要手动调用delete。标准款利用这个思想提供了智能指针,把资源放入对象内,对象的析构函数调用delete。

(1)获得资源后立即放入对象进行管理。即所谓的资源获取即初始化

(2)运行析构函数确保资源被释放

下面我们来学习一下标准款提供的智能指针:

(1)std::auto_ptr 现在基本上不用了。特点是对资源的所有权上面。auto_ptr采用可以采用copy语义来转移指针资源的所有权的同时将原指针置为NULL。因此不适合放在vector内,并且release()函数不会调用delete,reset()才ok

(2)boost::scoped_ptr 享有资源的独有权,禁止复制

(3)std::unique_ptr 不共享它的指针。它无法复制到其他 unique_ptr,无法通过值传递到函数,也无法用于需要副本的任何标准模板库 (STL) 算法。只能移动 unique_ptr。可以使用make_unique函数来进行构造

(4)std::shared_ptr 引用计数的智能指针,用于共享对象的所有权。是C + +标准库中一个聪明的指针,是为多个拥有者管理内存中对象的生命周期而设计的。在你初始化一个 shared_ptr 后,你可以复制它,把函数参数的值递给它,并把它分配给其它 shared_ptr 实例。所有实例指向同一个对象,并共享访问一个“控制块”,即每当一个新的 shared_ptr 被添加时,递增和递减引用计数,超出范围,则复位。当引用计数到达零时,控制块删除内存资源和自身。注意可能出现循环引用问题,可以利用weak_ptr来处理。

(5)std::weak_ptr 算是shared_ptr的一个补充,并不增加对象的引用计数,也没有*和->操作,只能通过lock()来返回一个shared_ptr(如果存在的话),可以通过expired()函数来判断对象是否被销毁。

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

并非所有资源都是heap-based,对于这种资源,智能指针往往不适合,我们需要建立自己的资源管理类。比如书中提到的mutex互斥器。当一个RAII对象被复制,会发生什么?以下是书中提到的四种选择:

(1)禁止复制。前面说过的private Uncopyable

(2)对底层资源使用智能指针

(3)深拷贝

(4)转移底部资源的所有权

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

因为很多API的都直接用的是指针,即直接指涉资源,所以智能指针需要提供对原始资源的访问接口。比如标准库中提供的shared_ptr提供get()方法,用以返回原生指针。或者用书中提到的隐式转换:

class A{    operator B() const    { return b; }}
条款16:成对使用new和delete时要采取相同的形式

即如果在new表达式中使用[],必须在相应的delete中也使用[]。保持一致

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

主要原因是new在编译器中相当于两部分操作:

(1)分配内存

(2)调用构造函数初始化

比如这个调用语句:foo(shared_ptr<A>(new A),func());执行顺序很可能是:

(1)执行分配内存操作

(2)调用func();

(3)调用构造函数进行初始化

如果在第二步抛出异常,则会造成资源的泄漏

原创粉丝点击