欢迎您光临本小站。希望您在这里可以找到自己想要的信息。。。

RAII名词解析

概念分析 water 2517℃ 0评论

资源获取即初始化( Resource Acquisition Is Initialization ),或称 RAII ,是一种 C++ 编程技术[1][2],它将必须在使用前请求的资源(被分配的堆内存、执行的线程、打开的接头、打开的文件、被锁的互斥、磁盘空间、数据库连接等——任何存在于受限供给中的事物)的生命周期绑定到一个对象的生存期

RAII 保证资源可用于任何会访问该对象的函数(资源可用性是一种类不变量,这会消除冗余的运行时测试)。它亦保证所有资源的在其控制对象的生存期结束时被释放,以获取顺序的逆序。类似地,若资源获取失败(构造函数以异常退出),则所有已为完全构造的对象和基类子对象所获取的资源,会被以初始化顺序的逆序释放。这会有效利用语言特性(对象生存期退出作用域初始化顺序以及栈回溯)以消除内存泄漏并保证异常安全。此技术的另一名称是作用域界定的资源管理( Scope-Bound Resource Management , SBRM ),根据 RAII 对象的生存期在退出作用域时结束这一基本状况。

RAII 可总结如下:

  • 将每个资源封装入一个类,这里

  • 构造函数请求资源,并建立所有类不变量或在它无法完成时抛出异常,

  • 析构函数释放资源并决不抛出异常;

  • 始终经由 RAII 类的实例使用满足要求的资源,该资源

  • 自身拥有自动存储期或临时生存期,或

  • 拥有绑定于自动或临时对象的生存期

移动语义令在维护资源安全的同时,在对象间、跨作用域,以及线程内外移动安全移动所有权成为可能。

拥有 open()/close() 、 lock()/unlock() ,或 init()/copyFrom()/destroy() 成员函数的类是非 RAII 类的典型的例子:

std::mutex m;

void bad() 

{

    m.lock();                    // 请求互斥

    f();                         // 若 f() 抛异常,则互斥决不被释放

    if(!everything_ok()) return; // 提早返回,互斥决不被释放

    m.unlock();                  // 若 bad() 抵达此语句,互斥才被释放

}

void good()

{

    std::lock_guard<std::mutex> lk(m); // RAII类:互斥请求即是初始化

    f();                               // 若f()抛异常,则释放互斥

    if(!everything_ok()) return;       // 提早返回,互斥被释放

}                                      // 若good()正常返回,则释放互斥

标准库

C++ 标准库遵循 RAII 管理其自身的资源: std::string 、 std::vector 、 std::thread ,以及多数其他类在构造函数(错误时抛出异常)中获取其资源,并在其析构函数(决不抛出)中释放之,且不要求显式清理。

另外,标准库提供几种 RAII包 装器以管理用户提供的资源:

  • std::unique_ptr 及 std::shared_ptr 以管理动态分配的内存,或以用户提供的删除器管理任何以普通指针表示的资源;

  • std::lock_guard 、 std::unique_lock 、 std::shared_lock 以管理互斥。

注意

RAII 不应用于不在使用前请求的资源: CPU 时间、核心,及缓存容量、熵池容量、网络带宽、电力消费、栈内存。

转载请注明:学时网 » RAII名词解析

喜欢 (0)or分享 (0)

您必须 登录 才能发表评论!