Resource acquisition is initialization (RAII)

本文详细解读了RAII编程范式在C++中的使用,通过实例阐述了如何通过构造函数进行资源分配,析构函数确保资源释放,实现异常安全的资源管理。讲解了为何RAII有助于简化资源管理,提升代码健壮性,并探讨了其与智能指针的关系。
摘要由CSDN通过智能技术生成

Resource acquisition is initialization (RAII) is a programming idiom used in several object-orientedstatically-typed programming languages to describe a particular language behavior. (C 语言没有构造析构函数,就不能直接用RAII)

In RAII, holding a resource is a class invariant, and is tied to object lifetimeresource allocation (or acquisition) is done during object creation (specifically initialization), by the constructor, while resource deallocation (release) is done during object destruction (specifically finalization), by the destructor.

In other words, resource acquisition must succeed for initialization to succeed. Thus the resource is guaranteed to be held between when initialization finishes and finalization starts (holding the resources is a class invariant), and to be held only when the object is alive. Thus if there are no object leaks, there are no resource leaks.

RAII is associated most prominently with C++ where it originated, but also other lanaguages. The technique was developed for exception-safe resource management in C++ during 1984–89, primarily by Bjarne Stroustrup and Andrew Koenig, and the term itself was coined by Stroustrup, RAII is generally pronounced as an initialism, sometimes pronounced as "R, A, double I".

C++11 example

The following C++11 example demonstrates usage of RAII for file access and mutex locking:

#include <fstream>
#include <iostream>
#include <mutex>
#include <stdexcept>
#include <string>

void WriteToFile(const std::string& message) {
  // |mutex| is to protect access to |file| (which is shared across threads).
  static std::mutex mutex;

  // Lock |mutex| before accessing |file|.
  std::lock_guard<std::mutex> lock(mutex);

  // Try to open file.
  std::ofstream file("example.txt");
  if (!file.is_open()) {
    throw std::runtime_error("unable to open file");
  }

  // Write |message| to |file|.
  file << message << std::endl;

  // |file| will be closed first when leaving scope (regardless of exception)
  // |mutex| will be unlocked second (from lock destructor) when leaving scope
  // (regardless of exception).
}

This code is exception-safe because C++ guarantees that all stack objects are destroyed at the end of the enclosing scope, known as stack unwinding. The destructors of both the lock and file objects are therefore guaranteed to be called when returning from the function, whether an exception has been thrown or not.

Local variables allow easy management of multiple resources within a single function: they are destroyed in the reverse order of their construction, and an object is destroyed only if fully constructed—that is, if no exception propagates from its constructor.

Using RAII greatly simplifies resource management, reduces overall code size and helps ensure program correctness. RAII is therefore recommended by industry-standard guidelines,[15] and most of the C++ standard library follows the idiom.

What is RAII?

https://medium.com/swlh/what-is-raii-e016d00269f9icon-default.png?t=LA92https://medium.com/swlh/what-is-raii-e016d00269f9

To RAII or Not to RAII?

To RAII or Not to RAII? - Fluent C++icon-default.png?t=LA92https://www.fluentcpp.com/2018/02/13/to-raii-or-not-to-raii/

A typical case for RAII: smart pointers

Smart pointers are classes that contain a pointer and take care of deleting them when going out of scope. If this sentence doesn’t make sense, you can look at this refresher on smart pointers, where we get into more details about the stack, the heap, and the principle of RAII illustrated with smart pointers.(这里明确了RAII 和smart pointers的关系: smart pointer是 RAII的一个usecase)

异常发生,还会退出作用域?

 todo verify:

The destructors of both the lock and file objects are therefore guaranteed to be called when returning from the function, whether an exception has been thrown or not.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值