Effective C++之资源管理

3 资源管理

所谓资源就是,一旦用了它,将来必须还给系统。

条款13:以对象管理资源。

有时仅仅用delete语句释放资源是行不通的,因为可能程序根本不会执行到delete语句。

我们可以把资源放进对象内,我们便可以依赖c++的“析构函数自动调用机制”确保资源被释放。

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

Effective C++之资源管理_第1张图片

由于auto_ptr被销毁时会自动删除它所指之物,所以一定要注意别让多个auto_ptr同时指向同一对象。为预防这个问题,auto_ptr有一个不寻常的性质:若通过copy构造函数或copy assignment操作符复制它们,它们会变成null,而复制所得的指针将取得资源的唯一拥有权!

auto_ptr的替代方案是“引用计数型智慧指针”。所谓RCSP(reference-couting smart pointer;)也是一个智能指针,持续追踪共有多少个对象指向某笔资源,并在无人指向它时自动删除该资源。

Effective C++之资源管理_第2张图片

上面的两种管理都不用于“C++动态分配数组”delete [];因为vector和string几乎总是可以取代动态分配而得的数组。

请记住:

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

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

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

当一个RII对象被复制时,可能会发生两个使用者同时使用一个资源的情况,所以:

禁止复制,如条款06;

对底层资源祭出“引用计数法”,如tr1::shared_ptr;

复制底部资源,深度拷贝,在赋值资源管理对象,,应该同时也赋值其所包覆的资源。

转移底部资源的拥有权:永远只有一个RAII对象指向一个未加工资源,如auto_ptr;

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

有些APIs直接访问原始资源如:

你想要这么调用它:

int days = daysHeld(pInv);

却通不过编译,因为daysHeld需要的是Investment*指针,你传给它的却是个类型为tr1::shared_ptr<Investment>的对象。

这时候你需要一个函数可将RAII class对象转换为其所含之原始资源。有两个做法可以达成目标:显示转换和隐式转换。

显示转换:提供一个get成员函数,返回智能指针内部的元素指针:

int days = daysHeld(pInv.get());

隐式转换:就像所有智能指针一样tr1::shared_ptr和auto_ptr也重载了operator ->和operator *,它们允许隐式转换至底部原始指针,还有提供隐式转换函数:

Effective C++之资源管理_第3张图片

请参见c++ primer14.9节

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

请记住:

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

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

请记住:

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

你可能感兴趣的:(Effective C++之资源管理)