C++中的RAII

部署运行你感兴趣的模型镜像
                       

有很多东西我们一直在用,但是不知道他的名字。

什么是RAII?

RAII是Resource Acquisition Is Initialization的缩写,用普通话将就是”资源获取即初始化”

为什么需要RAII?

看一段代码:

RawResourceHandle* handle=createNewResource();handle->performInvalidOperation();  // 发生异常...deleteResource(handle); // 永远不会释放
  
  • 1
  • 2
  • 3
  • 4

上面的代码所示是常见的内存泄露。更多的时候,我们使用C++11中的智能指针来解决上面的问题。
但是,如果不使用智能指针,那么是不是就是轮到RAII出场了。

如何使用RAII?

最简单的说,就是进行一个简单的封装:

class ManagedResourceHandle {public:   ManagedResourceHandle(RawResourceHandle* rawHandle_) : rawHandle(rawHandle_) {};   ~ManagedResourceHandle() {delete rawHandle; }private:   RawResourceHandle* rawHandle;};ManagedResourceHandle handle(createNewResource());handle->performInvalidOperation();
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

有了上面代码中的封装,就不需要担心产生异常了。

步骤:
1 Encapsulate a resource into a class

2 Use the resource via a local instance of the class*

3 The resource is automatically freed when the object gets out of scope

RAII与C++11

写一个write to file的函数:

#include <mutex>#include <iostream>#include <string> #include <fstream>#include <stdexcept>void write_to_file (const std::string & message) {    // mutex to protect file access (shared across threads)    static std::mutex mutex;    // lock mutex before accessing file    std::lock_guard<std::mutex> lock(mutex);    // try to open file    std::ofstream file("example.txt");    if (!file.is_open())        throw std::runtime_error("unable to open file");    // write message to file    file << message << std::endl;    // file will be closed 1st when leaving scope (regardless of exception)    // mutex will be unlocked 2nd (from lock destructor) when leaving    // scope (regardless of exception)}
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.youkuaiyun.com/jiangjunshow

您可能感兴趣的与本文相关的镜像

LobeChat

LobeChat

AI应用

LobeChat 是一个开源、高性能的聊天机器人框架。支持语音合成、多模态和可扩展插件系统。支持一键式免费部署私人ChatGPT/LLM 网络应用程序。

### RAII 是什么? RAII(Resource Acquisition Is Initialization)是一种 C++ 编程技术,中文意思是“资源获取即初始化”。它的核心思想是:**将资源的生命周期绑定到一个局部对象的生命周期上**。这样,当对象被创建时,资源会被正确获取;而当对象离开作用域时,资源也会自动被释放[^1]。 这种机制非常适合用于管理内存、文件句柄、网络连接、锁等资源,确保它们在使用完毕后能被及时释放,避免资源泄漏或程序异常崩溃导致的问题[^1]。 --- ### 为什么需要 RAII? 在传统的 C 或 C++ 编程中,开发者常常需要手动分配和释放资源,例如: ```cpp int* data = new int[100]; // 使用 data delete[] data; ``` 如果中间发生异常或者提前返回,很容易忘记 `delete[]`,从而造成内存泄漏。RAII 的出现就是为了解决这个问题——**它通过构造函数获取资源,在析构函数中释放资源,完全由编译器自动管理**。 --- ### RAII 的基本实现原理 RAII 利用了 C++ 中类的构造函数和析构函数机制: - **构造函数**:负责申请资源(如动态内存、打开文件等)。 - **析构函数**:负责释放资源(如 `delete` 内存、关闭文件等)。 由于 C++ 确保局部对象在离开作用域时会自动调用析构函数,因此可以保证资源的正确释放。 #### 示例:模拟智能指针的 RAII 实现 ```cpp class MyArray { private: int* data; public: MyArray(size_t size) { data = new int[size]; // 构造时分配资源 } ~MyArray() { delete[] data; // 析构时释放资源 } int& operator[](size_t index) { return data[index]; } }; void useResource() { MyArray arr(10); // 资源在栈上创建 arr[0] = 42; } // 函数结束,arr 离开作用域,自动调用析构函数释放内存 ``` 在这个例子中,`MyArray` 类封装了对堆内存的操作,用户无需手动调用 `delete[]`,资源会在对象销毁时自动回收。 --- ### RAII 的典型应用场景 1. **智能指针**:如 `std::unique_ptr` 和 `std::shared_ptr`,它们内部就是基于 RAII 实现的自动内存管理。 2. **文件操作**:使用 `std::ifstream` 或 `std::ofstream` 打开文件时,文件会在对象销毁时自动关闭。 3. **锁机制**:如 `std::lock_guard`,在构造时加锁,析构时解锁,避免死锁问题。 4. **数据库连接、网络连接等资源管理**:通过 RAII 包装连接对象,确保连接在使用完毕后被正确关闭。 --- ### RAII 的优势 - **自动资源管理**:资源在对象生命周期内自动分配和释放,无需手动干预。 - **异常安全**:即使函数中途抛出异常,也能保证资源被正确释放。 - **代码简洁清晰**:减少重复的资源释放代码,提升可性和可维护性。 - **避免资源泄漏**:有效防止因忘记释放资源而导致的内存泄漏等问题。 --- ### 注意事项 - 不要将 RAII 对象作为裸指针传递给其他函数,否则可能破坏其生命周期管理。 - 避免手动调用析构函数或重复释放资源。 - RAII 并不适用于所有场景,某些特定需求仍需手动管理资源。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值