Effective C++总结---3、资源管理

文章目录

  • 3、资源管理
    • 条款 13:以对象管理资源
    • 条款 14:在资源管理类中小心copying行为
    • 条款 15:在资源管理类中提供对原始资源的访问

3、资源管理

资源管理,一旦用了,就必须将其还给系统。资源包括动态内存分配,文件描述器,互斥锁,图形界面的字型,笔刷,数据库连接,网络sockets。

条款 13:以对象管理资源

遇到的问题:

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

在上述代码中,在heap上申请内存空间,然后经过“…”,然后使用delete释放申请的内存空间。

但是,在"…"的执行过程中,可能会存在return,抛出异常,或者发生在对createInvestment的使用及delete动作位于某个循环内,而该循环由于某个continue或goto语句过早退出。上述情况,使得delete语句不会执行,从而倒是内存泄漏。

解决方法:

  1. 将资源放入对象内,根据C++的析构函数自动调用机制确保资源被释放。
  2. 使用智能指针,shared_ptr对其进行管理,shared_ptr使用引用计数功能,当引用为0时,会自动释放申请的内存空间。
  3. 对于数组类型,使用c11中的array或者vector等stl的容器,他们不需要手动释放内存空间。
std::shared_ptr<Investment> createInvestment()
{
    ...
    return make_shared<Investment>(...);
}

void f()
{
    std::shared_ptr<Investment> pInv=createInvestment();
    ...
}

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

遇到的问题:
并非所有的资源都是在heap上的,有时候需要建立自己的资源管理类。

class Lock{
public:
    explicit Lock(Mutex *pm):mutexPtr(pm)
    {
        lock(mutexPtr);
    }
    ~Lock(){unlock(mutexPtr);}
private:
    Mutex *mutexPtr;
};

上面的代码是将互斥锁的函数进行了封装,我们只要创建对象,则在这个代码块中从这个对象创建起,将成为临界区。在脱离这个代码块时,将自动解锁。这个类遵循RAII原则,也就是”资源在构造期间获得,在析构期间释放“。

这里有几个问题:

当一个RAII对象被复制,会发生什么?

Lock ml1(&m);
Lock ml2(ml1);
  1. 禁止复制行为。
  2. 使用引用计数法。在类中使用shared_ptr对申请的内存空间进行管理。
class Lock{
public:
    explicit Lock(Mutex *pm):mutexPtr(pm,unlock)
    {
        lock(mutexPtr);
    }
private:
    std::shared_ptr<Mutex> mutexPtr;
};

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

你可能感兴趣的:(C++)