C++| 1-RAII

 

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();
}
复制代码

 

 

 

posted @   EnzoQiu  阅读(110)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
点击右上角即可分享
微信分享提示