RAII
1.什么是RAII
RAII(Resource Acquisition Is Initialization)即资源获取即初始化,是一种管理资源的机制。他说:使用局部对象来管理资源的技术称为资源获取即初始化;这里的资源主要是指操作系统中有限的东西如内存、网络套接字等等,局部对象是指存储在栈的对象,它的生命周期是由操作系统来管理的,无需人工介入;
2.实现原理
资源的使用一般经历三个步骤 :申请资源 、使用资源 、销毁资源。但是资源的销毁往往是程序员经常忘记的一个环节,所以程序界就想如何在程序员中让资源自动销毁呢?c++之父给出了解决问题的方案:RAII,它充分的利用了C++语言局部对象自动销毁的特性来控制资源的生命周期。我们可以利用局部对象销毁时会自动调用析构函数的机制来完成资源的释放等收尾操作。
3.应用
c++的stl中有很多应用了RAII机制,比如智能指针,锁(lock_guard、unique_lock)等。
**样例:**开发中我们经常会对一些资源用完后需要释放,但是如果一个函数中有多个退出分支,就需要写很多这种释放资源的操作。相对比较繁琐,同时代码也不够漂亮。于是可以借用RAII的机制,解决这种场景。
下面先看一段代码:
void Test()
{
// 获取文件资源
File* file = ...;
// 分支1
if (...) {
...
file.close();
return;
}
// 分支2
if (...) {
...
file.close();
return;
}
...
file.close();
}
是不是很挫,同时安全性比较差,比如某个分支忘记释放资源了,将导致资源泄露等问题。RAII机制用起来,如下:
using RaiiDeal = std::function<void()>;
class RaiiScope {
public:
RaiiScope(RaiiDeal deal) { m_function = deal; }
void Cancel(bool cancel) { m_isCancel = cancel; }
~RaiiScope()
{
if (!m_isCancel) {
m_function();
}
}
private:
RaiiDeal m_function {nullptr};
bool m_isCancel{false};
};
重写Test代码:
void Test()
{
// 获取文件资源
File* file = ...;
RaiiScope scope([&file](){ file.close()});
// 分支1
if (...) {
...
return;
}
// 分支2
if (...) {
...
return;
}
...
}
是不是觉得挺不错的,简洁又安全。是不是觉得开发中用一些这样的小技巧也挺有意思的~~。