【问题标题】:RAII Example from Wikipedia来自维基百科的 RAII 示例
【发布时间】:2013-04-26 18:42:19
【问题描述】:

我在查看the C++ example of RAII on wikipedia,发现了一些对我来说没有意义的东西。

这是代码 sn-p 本身,全部归功于维基百科:

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

void write_to_file (const std::string & message) {
    // mutex to protect file access
    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 1st when leaving scope (regardless of exception)
    // mutex will be unlocked 2nd (from lock destructor) when leaving
    //     scope (regardless of exception)
}

最后的评论说:“文件将首先关闭......互斥锁将被解锁......”。我了解 RAII 的概念,并且知道代码在做什么。但是,我看不出是什么(如果有的话)保证了该评论声称的顺序。

以问号结尾:什么保证文件在互斥锁解锁之前关闭?

【问题讨论】:

  • 维基百科在该代码下方立即回答了您的问题:“局部变量允许在单个函数中轻松管理多个资源:它们以构造的相反顺序被销毁,并且对象仅如果完全构造,则销毁——也就是说,如果没有异常从其构造函数传播。"
  • @Pubby:好吧,你看一下。我想我只是完全错过了我的眼睛。对不起。

标签: c++ wikipedia raii


【解决方案1】:

什么保证文件在互斥锁解锁之前关闭?

因为这就是 C++ 的设计方式:作用域对象(无论作用域是什么:类、函数、本地块……)以与初始化相反的顺序被销毁。真的没什么好说的了,这只是规范的一部分。

【讨论】:

  • 好的,这正是我想要的。我不知道这是保证。
  • @banshee_walk_sly:事实上,这是该语言的一个基本属性,因为它启用了 RAII 并因此启用了异常安全代码。但是异常安全是一个极其复杂的话题,太广泛了,无法在 SO 上完全涵盖。您可能想阅读 H.Sutter 的 Guru Of The Week 系列,即他讨论异​​常安全的系列。
【解决方案2】:

背后的原因是函数的调用堆栈是如何工作的。调用堆栈是存储函数局部变量的内存部分(除了其他东西)。调用堆栈就像一堆盘子一样工作。函数中的每个新变量都会在其堆中添加一个盘子。在函数结束时,所有板都从堆中移除,从顶部开始。这是创建的相反顺序。

有关调用堆栈的更多信息,您可以查看此处: http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 2021-08-13
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多