[转载] c++ RAII 机制

前言:

今天看到这个名词 RAII 我还没有见过 就看了一下

定义:

RAII技术被认为是C++中管理资源的最佳方法,进一步引申,使用RAII技术也可以实现安全、简洁的状态管理,编写出优雅的异常安全的代码。

资源管理
RAII是C++的发明者Bjarne Stroustrup提出的概念,RAII全称是“Resource Acquisition is Initialization”,直译过来是“资源获取即初始化”,也就是说在构造函数中申请分配资源,在析构函数中释放资源。因为C++的语言机制保证了,当一个对象创建的时候,自动调用构造函数,当对象超出作用域的时候会自动调用析构函数。所以,在RAII的指导下,我们应该使用类来管理资源,将资源和对象的生命周期绑定。

看个例子:

void Func()
{
  FILE *fp;
  char* filename = "test.txt";
  if((fp=fopen(filename,"r"))==NULL)
  {
      printf("not open");
      exit(0);
  }
  ... // 如果 在使用fp指针时产生异常 并退出
       // 那么 fp文件就没有正常关闭
	
  fclose(fp);
}

如果 出现了异常 return了 那么fp 就没法析构了 内存泄露了

RAII 就是来解决这样的问题了
析构 临时栈上面的对象

RAII的实现原理很简单,利用stack栈上的临时对象生命期是程序自动管理的这一特点,将我们的资源释放操作封装在一个临时对象中。

class FileRAII{
public:
    FileRAII(FILE* aFile):file_(aFile){}
    ~FileRAII() { fclose(file_); }//在析构函数中进行文件关闭
    FILE* get() {return file_;}
private:
    FILE* file_;
};

上面的代码可以改为

void Func()
{
  FILE *fp;
  char* filename = "test.txt";
  if((fp=fopen(filename,"r"))==NULL)
  {
      printf("not open");
      exit(0);
  }
  FileRAII fileRAII(fp);

 }

如果 在使用fp指针时产生异常 并退出
那么 fileRAII在栈展开过程中会被自动释放,析构函数也就会自动地将fp关闭

即使所有代码是都正确执行了,也无需手动释放fp,fileRAII它的生命期在此结束时,它的析构函数会自动执行!

这就是RAII的魅力,它免除了对需要谨慎使用资源时而产生的大量维护代码。在保证资源正确处理的情况下,还使得代码的可读性也提高了不少。

扫描二维码关注公众号,回复: 10148068 查看本文章

创建自己的RAII类

一般情况下,RAII临时对象不允许复制和赋值,当然更不允许在heap上创建,所以先写下一个RAII的base类,使子类私有继承Base类来禁用这些操作

class RAIIBase  
{  
protected:  
    RAIIBase(){}  
    ~RAIIBase(){}//由于不能使用该类的指针,定义虚函数是完全没有必要的  
private:      
    RAIIBase (const RAIIBase &);  
    RAIIBase & operator = (const RAIIBase &);  
    void * operator new(size_t size);   
    // 不定义任何成员  
};  
 
 
template<typename T>  
class ResourceHandle: public RAIIBase //私有继承 禁用Base的所有继承操作  
{  
public:  
    explicit ResourceHandle(T * aResource):r_(aResource){}//获取资源  
    ~ResourceHandle() {delete r_;} //释放资源  
    T *get()    {return r_ ;} //访问资源  
private:  
    T * r_;  
};

将Handle类做成模板类,这样就可以将class类型放入其中。另外, ResourceHandle可以根据不同资源类型的释放形式来定义不同的析构函数。

由于不能使用该类的指针,所以使用虚函数是没有意义的

一个demo 正好用的就是这个RAII 思想

c++ 11 std::lock_guard

转载 :https://blog.csdn.net/hunter8777/article/details/6327704

发布了178 篇原创文章 · 获赞 396 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/weixin_42837024/article/details/105048682