%% # 纲要 > 主干纲要、Hint/线索/路标 # Q&A #### 已明确 #### 待明确 > 当下仍存有的疑惑 **❓<font color="#c0504d"> 有什么问题?</font>** # Buffer ## 闪念 > sudden idea ## 候选资料 > Read it later %% # RAII > RAII(Resource Acquisition Is Initialization)**资源获取即初始化** > [!important] 什么是 RAII? > > RAII:指在 **==构造函数==** 中**请求/获取资源**,然后在 **==析构函数==** 中**释放资源**,从而实现**资源自动管理**的**编程范式/技术**。 在 RAII 范式下,每种**资源**都**封装在一个类**中,通过绑定 **资源的生命周期** 到 **对象的生命周期**, 利用 **==C++的作用域规则==** 来实现 **==自动资源管理==**(scope-based resource management): - **==构造函数==** 负责**获取资源**(Acquisition),初始化对象; - **==析构函数==** 负责**释放资源**(Release),析构对象。 由此,当**对象被创建时其所管理的资源随之被自动获取**,并**在对象生命周期结束时(例如离开作用域)自动释放**,从而避免内存泄露、文件描述符泄露等问题。 同时,RAII 保证 "**==异常安全==**",**在发生异常时,局部对象的析构函数仍将被调用**,保证通过 RAII 管理的资源将被正确清理和释放,避免异常导致的资源泄露。 ### RAII 的实际应用 RAII 是在 C++中广泛使用的**编程范式/技术**,常用于**自动管理资源(如动态内存、文件句柄、网络连接等)的生命周期** RAII 技术在 C++标准库中得到了广泛应用,例如: - **智能指针**(如 `std::unique_ptr`、`std::shared_ptr`)利用 RAII 管理动态分配的内存,确保对象不再使用时自动释放内存; - **标准容器**(如 `std::vector`、`std::string`)管理其内部资源,确保资源的正确分配与释放; - **基于 RAII 的互斥锁管理类**(`std::lock_guard`、`std::unique_lock`)在构造时自动加锁,在析构时自动解锁,简化了多线程编程中的同步操作。 ### RAII 实现示例 ```cpp title:raii_exam.cpp /* RAII (Resource Acquisition Is Initialization) 资源获得即初始化, 简单示例 * * MemoryBlock类封装了对动态内存的管理。 * - 当创建MemoryBlock对象时,它的构造函数会分配一块指定大小的内存。 * - 当对象的生命周期结束(例如,当function执行完毕并返回时), * MemoryBlock的析构函数会被自动调用,释放之前分配的内存。 */ class MemoryBlock { public: // 构造函数:分配资源 MemoryBlock(size_t length); // 析构函数: 释放资源 ~MemoryBlock(); // 禁止复制和赋值 MemoryBlock(const MemoryBlock&) = delete; MemoryBlock& operator=(const MemoryBlock&) = delete; private: size_t length; // 资源大小 int* data; // 指向资源的指针 }; MemoryBlock::MemoryBlock(size_t length) : length(length), data(new int[length]) { cout << "Resource allocated with length = " << length << endl; } MemoryBlock::~MemoryBlock() { delete[] data; cout << "Resource freed." << std::endl; } void func() { MemoryBlock block(1024); // 在栈上创建对象, 自动管理资源(资源是在堆上动态申请的内存空间) // 使用block... // 当func返回时, block的析构函数会被自动调用, 资源也随之释放. } int main() { func(); return 0; } ``` <br><br> # ♾️参考资料 # Footnotes