9 使用析构函数防止资源泄漏

有以下函数:

void function()
{
    Awesome * obj = new Awesome;
    obj->process();
    delete obj;
}

process发生异常时,function没有捕获异常;异常将会被传递到function的调用者,而process之后的代码则被跳过了,导致内存泄漏。

void function()
{
    Awesome * obj = new Awesome;
    try
    {
        obj->process();
    }
    catch(...)
    {
        delete obj;
        throw;
    }
    delete obj;
}

通过catch捕获异常并确保资源释放,但缺点是必须在正常运行情况下和异常情况下写多份资源清除代码。这样的代码写起来心烦又难以维护,而且看上去好像存在问题。

我们把__引入局部对象来管理这些动态资源,并把清除代码放入函数内局部对象的析构函数里,因为局部对象内存由栈管理,在离开生命周期后自动释放,在避免重复代码同时确保了没有资源泄漏__。

具体方法为用一个类指针对象代替指针。这个对象具有类似指针的行为,同时在其析构时释放资源,称为smart pointers(智能指针)C++11提供了三种智能指针:shared_ptrunique_ptrweak_ptr。在C++11之前只有auto_ptr

template <typename _Tp>
class auto_ptr
{
private:
    _Tp *_M_ptr;

public:
    explicit auto_ptr(_Tp *__p = 0) throw();
    auto_ptr(auto_ptr &__a) throw();
    auto_ptr &operator=(auto_ptr &__a) throw();
    ~auto_ptr();

    _Tp &operator*() const throw();
    _Tp *operator->() const throw();

    _Tp *get() const throw();
    _Tp *release() throw();
    void reset(_Tp *__p = 0) throw();
};
  • 指针资源自动释放
  • 支持拷贝构造
  • 支持operator-> / operator *解引用
  • 保持指针持有者唯一

auto_ptr具备原始指针的所有功能,两者的使用场景完全等同。修改后的函数如下:

void function()
{
    auto_ptr<Awesome> obj();
    obj->process();
    //delete obj; //不需要显示调用析构函数
}

智能指针背后的思想是:用一个对象存储需要被自动释放的资源,并依靠对象的析构函数来释放资源。类似的思想不只是可以在指针上,还可以用在其它资源的分配和释放上。

上一篇:C++常用库


下一篇:第三篇:事务