RAII = Resource Acquisition Is Initialization
RAII惯用法可以用于管理各种资源,例如内存、文件、同步锁、其它资源等

1. RAII管理内存的例子

1.1. 不用RAII的写法

A * create()
{
    retrun new A();
}

此处在堆中创建了一个A,如何保证它将来会被释放?

1.2. 定义RAII帮助类

class Wrapper
{
public:
    explicit Wrapper(A * ptr = nullptr)
        : ptr_(ptr){}
    ~Wrapper()
    {
        delete ptr_;
    }
    A * get() const
    {
        return ptr_;
    }
private:
    A * ptr_;
};

1.3. 使用RAII帮助类的写法

Wrapper create_with_wrapper()
{
    Wrapper w(create());
    return w;
}

利用}自动调用析构函数的原理,当w的栈空间被清理时,w.ptr_所指向的空间也会被自动清理,不用担心A指针的泄漏。
遗留问题:值语义对象作为返回值会发生“copy”,能不能用“move”代替“copy”?

2. RAII管理同步锁的例子

2.1. 不使用RAII的写法

std::mutex mtx;
void func()
{
    mtx.lock();    // 加锁
    。。。。        // 同步工作
    mtx.unlock();  // 释放锁
}

潜在风险:

  1. 忘记写“释放锁”
  2. 同步工作中有提前返回,每个返回之前都要写“释放锁”
  3. 同步工作中发生异常,每个异常处理中都要写“释放锁”

2.2. 使用RAII的写法

std::mutex mtx;
void  func()
{
    std::lock_guard<std::mutex> guard{mtx};   // 加锁
    。。。。                                   // 同步工作
}                                             // 自动释放锁

results matching ""

    No results matching ""