C++中的RAII技法

时间:2024-10-25 18:35:08

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

所谓资源就是,一旦用了它,将来必须还给系统。如果不这样,糟糕的事情就会发生。常见的资源包括内存、文件描述符、互斥锁、数据库连接、网络sockets。

以对象管理资源的两个关键想法:获得资源后立刻放进管理对象;管理对象运用析构函数确保资源被释放。

对于heap-based资源,常被使的RAII classes分别是shared_ptrauto_ptr,有时可考虑boost::shared_arrayboost::scoped_array

对于非heap-based资源,常使用RAII手法封装资源的取得与释放,这时需要考虑RAII对象被复制,常见的行为是禁制复制、施行引用计数法并指定删除器、使用深度拷贝复制底部资源、转移底部资源的拥有权。

对于以上两种资源都需要考虑RAII对象析构时抛出异常的问题。

示例代码如下。

#include <mutex>
#include <iostream>
#include <string>
#include <fstream>
#include <stdexcept> void write_to_file (const std::string & message) {
// mutex to protect file access (shared across threads)
static std::mutex mutex; // lock mutex before accessing file
std::lock_guard<std::mutex> lock(mutex); // try to open file
std::ofstream file("example.txt");
if (!file.is_open())
throw std::runtime_error("unable to open file"); // write message to file
file << message << std::endl; // file will be closed 1st when leaving scope (regardless of exception)
// mutex will be unlocked 2nd (from lock destructor) when leaving
// scope (regardless of exception)
}

参考:《Effective C++》、wikipediacppreference