C++11:RAII

简介: C++11:RAII

RAII

Resource Acquisition Is Initialization 资源获取即初始化时机。

原理:利用对象的生命周期来管理资源,对象离开作用域自动调用析构函数。

1、RAII 特征

  • 在构造时初始化资源或托管资源
  • 析构时释放资源
  • 一般表达对象语义,不允许复制或者赋值
  • 提供若干访问资源的方法
// RAII类解决堆空间对象的释放问题
 template <typename T>
 class RAII {
 public:
     // 通过构造函数托管资源 
     RAII(T * p)
     : _p(p) {}
     // 获取所托管的资源的原生的裸指针
     T * get() { return _p; }
     // 访问资源的方法 
     T* operator->() { return _p; }
     T & operator*() { return *_p; }
     // 重置要托管的指针  
     void reset(T * p) {
         if(_p) {
             delete _p;
             _p = p;
         }
     }
     ~RAII() {
         if(_p) {
             delete _p;
         }
     }
 private:
     T * _p;
 };
 void test0() {
     //智能指针(对象)托管指针
     RAII<Point> pPoint(new Point(1, 2));
     pPoint->print();
     (*pPoint).print();
     //获取所托管的资源的原生的裸指针
     cout << "address:" << pPoint.get() << endl;
 } 
 int main(void) {
     test0();
     return 0;
 }

2、对象语义

值语义:可以进行复制控制。

对象语义:不能进行复制控制,两种实现方法。

  • 将拷贝构造函数和赋值运算符函数设置为私有(C++11前)
private:
 //表达对象语义,禁止复制
 SafeFile(const SafeFile &);
 SafeFile & operator=(const SafeFile&);
  • 将拷贝构造函数和赋值运算符函数使用 =delete(C++11标准)
SafeFile(const SafeFile &) = delete;
 SafeFile & operator=(const SafeFile&) = delete;

例:SafeFile 的实现

//对象语义SafeFile
 #include <stdio.h>
 #include <iostream>
 #include <string>
 #include <fstream>
 using std::cout;
 using std::endl;
 using std::string;
 using std::ifstream;
 class SafeFile {
 public:
     // 构造函数初始化资源
     SafeFile(const string & filename)
     : _fp(nullptr) 
     {
         _fp = fopen(filename.c_str(), "a+");
         if(!_fp) {
             cout << "file " << filename << "not found" << endl;
         }
     }
     SafeFile(FILE * fp)
     : _fp(fp)
     {}
     void write(const string & str) {
         fwrite(str.c_str(), 1, str.size(), _fp);
     }
     // 析构时释放资源
     ~SafeFile() {
         if(_fp) {
             fclose(_fp);
             cout << "fclose(_fp)" << endl;
         }
     }
     // 2、C++11标准
     // 将拷贝构造函数和赋值运算符函数从当前类中删除掉
     SafeFile(const SafeFile &) = delete;
     SafeFile & operator=(const SafeFile&) = delete;
 private:
     // 1、C++11标准之前
     // 将拷贝构造函数和赋值运算符函数设为私有
     // SafeFile(const SafeFile &);
     // SafeFile & operator=(const SafeFile&);
 private:
     FILE * _fp;
 };
 void test0() {
     // 通过对象来托管文件指针,不需要进行文件指针的回收
     // sf对象生命周期被销毁时,会自动调用其析构函数,在析构函数内完成资源回收
     SafeFile sf("test.txt");
     // 只需要负责对文件指针进行操作即可
     sf.write("this is a test line\n");
     FILE * fp = nullptr;
     SafeFile sf2(fp);
     //sf2 = sf;//error  调用赋值运算符函数
     //SafeFile sf3 = sf;//error 调用拷贝构造函数
 } 
 void test1() {
     // C++的所有流对象都是不能进行复制的,表达对象语义(客观对象都是独一无二的)
     ifstream ifs("test.txt");
     ifstream ifs2 = ifs; //调用拷贝构造函数
 }
 int main(void) {
     test0();
     return 0;
 }
相关文章
|
2月前
|
安全 程序员 编译器
C++中的RAII(资源获取即初始化)与智能指针
C++中的RAII(资源获取即初始化)与智能指针
24 0
|
18天前
|
C++
【C++11(三)】智能指针详解--RAII思想&循环引用问题
【C++11(三)】智能指针详解--RAII思想&循环引用问题
|
2月前
|
算法 程序员 数据库连接
深入探索C++中的RAII原则:资源管理的艺术 (In-Depth Exploration of RAII in C++: The Art of Resource Management)...
深入探索C++中的RAII原则:资源管理的艺术 (In-Depth Exploration of RAII in C++: The Art of Resource Management)...
49 2
|
C++
C++的RAII在WebKit中的应用
先看下面这段WebKit中的代码: { NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); //Do something else.
911 0
|
安全 C++
【C++设计技巧】C++中的RAII机制
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ 1.概念 Resource Acquisition Is Initialization 机制是Bjarne Stroustrup首先提出的。
1044 0
|
4天前
|
设计模式 安全 算法
【C++入门到精通】特殊类的设计 | 单例模式 [ C++入门 ]
【C++入门到精通】特殊类的设计 | 单例模式 [ C++入门 ]
14 0
|
5天前
|
C语言 C++
【C++】string类(常用接口)
【C++】string类(常用接口)
13 1
|
2天前
|
编译器 C++
【C++】继续学习 string类 吧
首先不得不说的是由于历史原因,string的接口多达130多个,简直冗杂… 所以学习过程中,我们只需要选取常用的,好用的来进行使用即可(有种垃圾堆里翻美食的感觉)
7 1