RAII的本质是构造函数获取资源、析构函数释放资源;它是利用对象生命周期自动管理资源的惯用法,要求资源获取在构造函数中、释放在noexcept析构函数中,优先使用std::unique_ptr等智能指针并自定义删除器处理非内存资源。

RAII的本质是构造函数获取资源、析构函数释放资源
RAII不是语法特性,而是C++中利用对象生命周期自动管理资源的惯用法。核心在于:资源获取(如 new、fopen、pthread_mutex_init)必须放在构造函数里,资源释放(如 delete、fclose、pthread_mutex_destroy)必须放在析构函数里,且析构函数必须是 noexcept(否则异常途中栈展开失败会直接调用 std::terminate)。
常见错误是把资源指针裸露在外,或在析构中抛出异常:
class BadFileHandle {
FILE* fp;
public:
BadFileHandle(const char* name) { fp = fopen(name, "r"); }
~BadFileHandle() { if (fp) fclose(fp); } // ❌ 未检查 fclose 是否失败,且没声明 noexcept
};
std::unique_ptr 和 std::shared_ptr 已覆盖绝大多数场景
手写 RAII 类容易出错,优先用标准智能指针。它们默认行为就是 RAII:构造时接管原始指针,析构时自动调用删除器。
-
std::unique_ptr适合独占资源(如堆内存、文件描述符),移动语义明确,零开销 -
std::shared_ptr适合共享所有权(如缓存对象),但有引用计数开销和循环引用风险 - 对非内存资源(如文件句柄、锁),必须自定义删除器:
std::unique_ptr或 lambda
示例——安全封装 POSIX 文件描述符:
FILE*
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











