RAII (Resource Acquisition Is Initialization) 翻译为中文是「资源获取即初始化」。
通常用来做局部资源清理或者防止忘记解锁导致死锁:
class LockGuard {
public:
LockGuard() { lock(); }
~LockGuard() { unlock(); }
private:
static pthread_mutex_t _fastmutex;
void lock() {
pthread_mutex_lock(&_fastmutex);
}
void unlock() {
pthread_mutex_unlock(&_fastmutex);
}
};
pthread_mutex_t LockGuard::_fastmutex(PTHREAD_MUTEX_INITIALIZER);
以上代码定义了一个局部锁,锁生效的域和这个类的生命周期所在域一致。
在 C++ 里,如果 LockGuard
使用方式不对会导致锁无效:
错误的代码:
void foo() {
// 生成的是匿名对象
LockGuard(); // 匿名对象在这行代码之后就被释放,锁也就无效了
}
匿名对象的生命周期很短,超出它所在行就会被析构,所以正确的做法是使用具名的局部变量。
正确的代码:
void foo() {
// 具名的局部对象,生命周期是它所在的作用域
LockGuard _guard_;
}
另外,不用担心没有被引用的局部对象会被编译器优化,编译器足够聪明,会根据类的构造/析构方法是否为空来判断要不要保留这个局部对象。