RAII,完整的英文是 Resource Acquisition Is Initialization,是 C++ 所特有的资源管理 方式。
RAII 依托栈和析构函数,来对所有的资源——包括堆内存在内——进行管理。对 RAII 的 使用,使得 C++ 不需要类似于 Java 那样的垃圾收集方法,也能有效地对内存进行管理。
RAII 的存在,也是垃圾收集虽然理论上可以在 C++ 使用,但从来没有真正流行过的主要原因。
内存泄漏
事实说明,漏掉 delete 是一种常见的情况,这叫“内存泄漏” 。 代码例子。
void foo() { bar* ptr = new bar(); … delete ptr; }
两个问题:
1. 中间省略的代码部分也许会抛出异常,导致最后的 delete ptr 得不到执行。
2. 更重要的,这个代码不符合 C++ 的惯用法。在 C++ 里,这种情况下有 99% 的可能性 不应该使用堆内存分配,而应使用栈内存分配。
RAII
对象没办法只能存在堆上的情况, 应当在外面套一个栈实体对象,并利用该实体退出作用域时调用栈中析构函数的行为,去自动清除申请的引用对象。
class shape_wrapper { public: explicit shape_wrapper( shape* ptr = nullptr) : ptr_(ptr) {} ~shape_wrapper() { delete ptr_; } shape* get() const { return ptr_; } private: shape* ptr_; }; void foo() { … shape_wrapper ptr_wrapper( create_shape(…)); … }
这种清理并不限于释放内存,也可以是:
关闭文件(fstream 的析构就会这么做)
释放同步锁
释放其他重要的系统资源
应该:
std::mutex mtx; void some_func() { std::lock_guard<std::mutex> guard(mtx); // 做需要同步的工作 }
而不是:
std::mutex mtx; void some_func() { mtx.lock(); // 做需要同步的工作…… // 如果发生异常或提前返回, // 下面这句不会自动执行。 mtx.unlock(); }
标签:RAII,wrapper,shape,C++,ptr,内存 From: https://www.cnblogs.com/JohnsonQ/p/16994803.html