C++的RAII机制

一说到C++开发的难点,很多人便会想到内存资源的申请和释放,一不小心便会出现内存泄漏的问题。或许有同学会有疑问,只要每次在new出一块空间使用完之后记得delete操作不就好了吗,为啥要担心内存发生泄漏呢,比如下面这段代码

1
2
3
4
5
6
void func()
{
int* p = new int();
//do somethings
delete p;
}

虽然在使用完之后也记得delete操作了,但是有一个存在的隐患就是无法保证newdelete之间的代码不会出现异常而导致无法执行到delete操作。
由程序员来管理资源的申请和释放果然是一件折磨人的事情。回忆一下 C++ 的局部变量,当代码执行离开一个局部作用域时,属于该作用域的局部变量都会被销毁。既然这样,我们可以将资源和一个局部变量的生命周期绑定在一起。让局部对象代替我们进行资源的释放不就可以了。其实这就是RAII设计理念的一个通俗解释。

RAII 是 resource acquisition is initialization 的缩写,意为“资源获取即初始化”。它是 C++ 之父 Bjarne Stroustrup 提出的设计理念,其核心是把资源和对象的生命周期绑定,对象创建获取资源,对象销毁释放资源。在RAII 的指导下,C++ 把底层的资源管理问题提升到了对象生命周期管理的更高层次。

下面我们来看一下在RAII理念的指导下内存资源的申请和释放的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
template <class T>
class Handler
{
public:
Handler(T *p) :_p(p){}
~Handler()
{
delete _p;
}
private:
T *_p;
};
int main()
{
Handler<int> handler(new int);
return 0;
}

handler对象离开该作用域后,就会自动调用析构函数把申请的内存资源释放出来了。RAII设计理念还被应用于锁的锁定与解锁上,这样一来我们也不用担心因为程序的异常而造成死锁的问题。像智能指针lock_guard等高大上的东西都是基于RAII设计理念实现的。

-------------本文结束您的阅读与肯定是我持续装*的最大动力-------------