Resource Acquisition Is Initialization (RAII)

RAII 是 C++ 之父 Bjarne Stroustrup (比雅尼·史特勞斯特魯普) 所提出來的,關於物件導向的資源管理問題,一種簡潔的解決方法。主要解決了 resource leak 的問題。

Object 建立的時候, resource 取得的是時候是經由 constructor 來初始. 結束的時候便透過 destructor來釋放. 讓 life cycle of a resource 和 lifetime of an object 完全綁在一起,藉以解決可能的 resource leak 問題。

Resource Acquisition Is Initialization or RAII, is a C++ programming technique which binds the life cycle of a resource that must be acquired before use (allocated heap memory, thread of execution, open socket, open file, locked mutex, disk space, database connection—anything that exists in limited supply) to the lifetime of an object.

範例:Mutex

std::mutex m;
 
void bad() 
{
    m.lock();                    // acquire the mutex
    f();                         // if f() throws an exception, the mutex is never released
    if(!everything_ok()) return; // early return, the mutex is never released
    m.unlock();                  // if bad() reaches this statement, the mutex is released
}
 
void good()
{
    std::lock_guard<std::mutex> lk(m); // RAII class: mutex acquisition is initialization
    f();                               // if f() throws an exception, the mutex is released
    if(!everything_ok()) return;       // early return, the mutex is released
}                                      // if good() returns normally, the mutex is released
  • bad function : mutex 有可能不會被 release。
  • good function : mutex 被包在 class 中,因此當離開 scope 時,object 會 call destructor 而自動 release 。

範例:File

class file
{
public:
    file(string const& name) {
        m_fileHandle=fopen(name.cstr());
    }
    ~file() {
        fclose(m_fileHandle);
    }
    //
private:
    handle m_fileHandle;
}
void fun1() {
    file myfile("my.txt");
     //操作文件
} //destructor

Conclusion

  1. 利用 class 封裝所有 resource :
    • the constructor acquires the resource and establishes all class invariants or throws an exception if that cannot be done.
    • the destructor releases the resource and never throws exceptions
  2. 藉由 class 的實體 來操作 resource。

Reference

Comments