tartarus's bolg tartarus's bolg
  • Linux and Unix Guide
  • CMake
  • gcc
  • gdb
  • bash
  • GNU Make
  • DDCA-ETH
  • CS106L
  • CS144
  • NJU PA
  • NJU OS(jyy)
  • C
  • C++
  • Python
  • reveal-md
  • LaTex
  • Paper Reading
  • TBD
  • Linux and Unix Guide
  • CMake
  • gcc
  • gdb
  • bash
  • GNU Make
  • DDCA-ETH
  • CS106L
  • CS144
  • NJU PA
  • NJU OS(jyy)
  • C
  • C++
  • Python
  • reveal-md
  • LaTex
  • Paper Reading
  • TBD
  • c

  • cpp

    • Introduction
    • RAII
      • 介绍
      • 概念解释
        • RAII
    • keyword-friend
    • brace-initialization
    • inner-class
  • Programming_Knowledge
  • cpp
tartarus
2023-04-20
目录

RAII

# 介绍

RAII (Resource Acqusition Is Initialization): 是 C++ 中非常 powerful 的一个概念。但是它的名字起的确实很烂,以至于作者都对他起的名字一直感到后悔。更好的名字应该叫做:

  • Constructor Acquires, Destructor Releases
  • Scope Based Resource Management

# 概念解释

在解释 RAII 前,我们需要先了解什么是 recourse?

Things that we have a finite supply of and so we need to be able to control their usage.

比如: file handler, Heap Memory, Newwork Sockets, Locks (in OS) 都是 resouces.

因为资源是有限的,我们应该在使用时申请资源,用完后需要释放资源。如果不释放,就会造成资源泄漏 (leak),进而可能导致别的程序无法申请到该资源。

以 C 语言中打开文件并打引其中的内容为例子说明:

void printFile(const char* name) {
  // acquire file resouce
  File* f = fopen(name, "r");
  //print contents of f
  ...
  //release file resouce
  fclose(f)
}
1
2
3
4
5
6
7
8

这样的资源管理看起来是没有问题的,需要使用时申请资源,使用完毕后释放资源,但是假设在释放之前出现 return 语句使得函数提前返回或者忘记释放资源,那么被获取的资源就永远得不到释放,产生资源泄漏 (leak)。

# RAII

为了解决这个问题,可以在 C++ 中使用 RAII 对资源进行管理:

我们可以构造一个类,在该类的 Constructor 中申请资源 (Resoruce Acquired when you initialize an object),在 destructor 中释放资源。

这样如果声明了一个这个类的对象,那么就可以在构造对象的时候就获取当前对象所需要的全部资源,使用完毕后自动通过 destructor 释放资源。

因此我们可以创建这样一个类 FileObj ,用来管理资源:

class FileObj {
public:
  FILE* ptr;
  FileObj(char* name)
    : ptr(fopen(name, "r")) {}
  ~FileObj() {
  fclose(ptr);
  }
};
1
2
3
4
5
6
7
8
9

这样我们的 printFile 函数就可以改写为:

void printFile(const char* name) {
  // initialization will acquire resources
  FileObj fobj(name);

  // print contents of f

  // FileObj destructor will release resources
}
1
2
3
4
5
6
7
8

当函数调用结束后,不需要手动释放资源,资源会被自动调用的 destructor 被释放。

参考:

  • Standford CS106L RAII (opens new window)
  • What is meant by Resource Acquisition is Initialization (RAII)? (opens new window)
上次更新: 12/27/2023, 8:55:47 AM
Introduction
keyword-friend

← Introduction keyword-friend→

Theme by Vdoing | Copyright © 2023-2023 tartarus | CC BY-NC-SA 4.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式