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;
 }
相关文章
|
6月前
|
安全 程序员 编译器
C++中的RAII(资源获取即初始化)与智能指针
C++中的RAII(资源获取即初始化)与智能指针
82 0
|
3月前
|
存储 Java 程序员
面向对象编程(C++篇4)——RAII
面向对象编程(C++篇4)——RAII
37 0
|
5月前
|
安全 C++ 开发者
C++一分钟之-RAII资源获取即初始化
【6月更文挑战第24天】RAII是C++中一种关键的资源管理技术,它利用对象生命周期自动获取和释放资源,减少内存泄漏。通过构造函数获取资源,析构函数释放资源,确保异常安全。优势包括自动性、异常安全和代码清晰。使用智能指针如`std::unique_ptr`和`std::shared_ptr`,以及标准库容器,可以避免手动管理。自定义RAII类适用于非内存资源。代码示例展示了智能指针和自定义RAII类如何工作。掌握RAII能提升程序的可靠性和可维护性。
72 6
|
6月前
|
安全 Linux 编译器
从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr(下)
从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr
41 3
|
6月前
|
安全 编译器 C语言
从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr(中)
从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr
42 1
|
6月前
|
安全 编译器 C语言
从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr(上)
从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr
33 0
|
6月前
|
C++
【C++11(三)】智能指针详解--RAII思想&循环引用问题
【C++11(三)】智能指针详解--RAII思想&循环引用问题
|
6月前
|
算法 程序员 数据库连接
深入探索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)...
214 2