条款13:以对象管理资源

Use objects to manage resources.

资源取得时机便是初始化时机(Resource Acquisition Is Initialization,RAII)

资源泄漏

如果一个函数使用了动态内存,则应该负责释放掉它:

void f() {
    Investment* pInv = new Investment();
    ...
    delete pInv;
}

但有些情况下,函数可能无法删除它得到的资源,比如在 ”...“ 区域中过早地使用 return 语句。

智能指针

为了确保函数内的资源总能被释放,我们需要将资源放进对象内,当控制流离开函数时,该对象的析构函数会自动释放资源。

标准程序库提供的 auto_ptr 即为针对这种需求的产品,它是个类指针(pointer-like)对象,也就是所谓的”智能指针“,其析构函数自动对其所指向对象调用 delete。

void f() {
    std::auto_ptr<Investment> pInv(new Investment());
    ...
}

智能指针的两个关键想法在于:

  • 获得资源后立刻放进管理对象(managing object)内;

  • 管理对象(managing object)运用析构函数确保资源被释放;

由于 auto_ptr 被销毁时会自动删除它所指向的对象,所以一定要注意别让多个智能指针指向同一个对象。为了预防这个问题,智能指针有一个特性:若通过 copy 构造函数或 copy assignment 操作符赋值它们,它们为变成 null,而复制所得的指针将获得对象的唯一拥有权。

std::auto_ptr<Investment> pInv1(new Investment());    // pInv1 指向资源;
sdt::auto_ptr<Investment> pInv2(pInv1);               // pInv2 指向资源,pInv1指向null;
pInv1 = pInv2;                                        // pInv2 指向null,pInv1指向资源;

引用计数型智慧指针

引用计数型智慧指针(reference-counting smart pointer,RCSP)也是一个智能指针,不同的是它会持续跟踪共有多少对象指向某笔资源,并在无人指向它时自动删除该资源。

void f() {
    std::tr1::shared_ptr<Investment> pInv(new Investment());
    ...
}

注意智能指针释放资源

智能指针在其析构函数内做 delete 而不是 delete[],对于数组的资源管理,一般用 vector 和 string 替代。

Last updated

Was this helpful?