什么是资源获取初始化(RAII)?


当前回答

RAII概念只是一个C堆栈变量的想法。最简单的解释。

其他回答

对于一个非常强大的概念来说,这是一个非常糟糕的名字,而且可能是c++开发人员在转向其他语言时最容易忽略的事情之一。有一些人试图将这个概念重命名为作用域绑定资源管理(Scope-Bound Resource Management),尽管它似乎还没有流行起来。

When we say 'Resource' we don't just mean memory - it could be file handles, network sockets, database handles, GDI objects... In short, things that we have a finite supply of and so we need to be able to control their usage. The 'Scope-bound' aspect means that the lifetime of the object is bound to the scope of a variable, so when the variable goes out of scope then the destructor will release the resource. A very useful property of this is that it makes for greater exception-safety. For instance, compare this:

RawResourceHandle* handle=createNewResource();
handle->performInvalidOperation();  // Oops, throws exception
...
deleteResource(handle); // oh dear, never gets called so the resource leaks

用RAII这个

class ManagedResourceHandle {
public:
   ManagedResourceHandle(RawResourceHandle* rawHandle_) : rawHandle(rawHandle_) {};
   ~ManagedResourceHandle() {delete rawHandle; }
   ... // omitted operator*, etc
private:
   RawResourceHandle* rawHandle;
};

ManagedResourceHandle handle(createNewResource());
handle->performInvalidOperation();

在后一种情况下,当抛出异常并展开堆栈时,局部变量将被销毁,这确保了我们的资源被清理并且不会泄漏。

我已经多次回到这个问题并阅读了它,我认为投票最多的答案有点误导。

RAII的关键是:

“这(主要)不是关于捕捉异常,主要是关于管理资源的所有权。”

得票最高的答案夸大了例外安全,这让我很困惑。

事实是:

You still need to write try catch to handle exceptions (check the 2 code example below), except that you don't need to worry about releasing resources for those classes using RAII in your catch block. Otherwise, you need to look up each non-RAII class's API to find which function to call so as to release acquired resources in catch block. RAII simply save these work. Similar as above, when coding with RAII, you simply write less code, no need to call releasing resouce functions. All the clean-ups are done in the destructor.

另外,请查看我在上面的评论中发现的两个有用的代码示例。

https://ideone.com/1Jjzuc, https://ideone.com/xm2GR9

附言:我们可以用..来和蟒蛇比较。As语句,你也需要捕获可能发生在with块内部的异常。

Manual memory management is a nightmare that programmers have been inventing ways to avoid since the invention of the compiler. Programming languages with garbage collectors make life easier, but at the cost of performance. In this article - Eliminating the Garbage Collector: The RAII Way, Toptal engineer Peter Goodspeed-Niklaus gives us a peek into the history of garbage collectors and explains how notions of ownership and borrowing can help eliminate garbage collectors without compromising their safety guarantees.

RAII概念只是一个C堆栈变量的想法。最简单的解释。

RAII类有三个部分:

该资源在析构函数中被放弃 类的实例是堆栈分配的 资源是在构造函数中获取的。这部分是 可选,但很常见。

RAII代表“资源获取是初始化”。RAII的“资源获取”部分是你开始某些必须在之后结束的内容,例如:

打开文件 分配内存 获取锁

“is initialization”部分意味着获取发生在类的构造函数内部。

https://www.tomdalling.com/blog/software-design/resource-acquisition-is-initialisation-raii-explained/