RAII(Resource Acquisition Is Initialization)即资源获取即初始化,这里的资源是:内存,网络,文件等对象。一个资源的生命周期一般包括:获取资源,使用资源, 释放资源三个步骤。不同的编程语言对资源的管理也离不开这三个方面,其中释放资源应该是最头疼的。C语言采用纯手动回收;Go语言采用的是垃圾回收器;Rust语言采用所有权机制回收(没有垃圾回收器的性能损耗,却能达到其效果);而C++即可以手动回收,也可以通过RAII的方式进行回收。其中RAII的回收机制和Rust的回收机制有很多相似的地方。下面看一个例子:
#include <iostream>
class resource {
int *m_array;
public:
resource(const resource&) = delete;
void operator= (const resource&) = delete;
resource(int size) {
m_array = new int[size];
}
~resource() {
delete []m_array;
}
};
int main() {
resource r(100);
}
上面是通过RAII方式构造一个类的典型写法。整个过程包括以下步骤:
- 设计一个类对资源进行封装
- 在构造函数中初始化资源
- 在析构函数中释放资源
这个过程很简单却无比强大,我们在使用该类时不需要关心内部资源释放会被释放,编译器和作用域规则将接管对象的资源管理细节。
那使用RAII带来什么好处呢?
- 从繁琐的资源管理中脱身
- 即使发生异常,资源也能正确释放
- 有效的避免空指针引发的bug
RAII典型应用:
- std::unique_ptr 和 std::shared_ptr 管理堆上资源
- std::lock_guard, std::unique_lock, std::shared_lock 管理锁资源