代码之家  ›  专栏  ›  技术社区  ›  AshleysBrain

在抛出的异常中销毁字符串临时变量

  •  5
  • AshleysBrain  · 技术社区  · 15 年前

    考虑下面的代码:

    std::string my_error_string = "Some error message";
    
    // ...
    
    throw std::runtime_error(std::string("Error: ") + my_error_string);
    

    传递给运行时错误的字符串是由字符串的 operator+ . 假设此异常的处理方式如下:

    catch (const std::runtime_error& e)
    {
        std::cout << e.what() << std::endl;
    }
    

    字符串的 摧毁?语言规范对此有什么要说的吗?另外,假设运行时错误 const char* 然后像这样抛出:

    // Suppose runtime_error has the constructor runtime_error(const char* message)
    throw std::runtime_error((std::string("Error: ") + my_error_string).c_str());
    

    现在操作符+返回的临时字符串何时被销毁?它会在catch块试图打印它之前被销毁吗?这就是为什么运行时错误接受std::string而不是const char*?

    3 回复  |  直到 15 年前
        1
  •  5
  •   CB Bailey    15 年前

    作为临时对象(12.2) + 将被销毁作为评估的最后一步 充分表达 (1.9/9)包含它。在这种情况下 抛出表达式

    抛出表达式 构造一个临时对象 异常对象 ) (15.1) ( std::runtime_error 在这种情况下)。世界上所有的临时工 会在战争结束后被摧毁 已经建成。只有在对 抛出表达式 已完成,因为临时变量的销毁是此评估的一部分,所以它们将在销毁自输入try块(15.2)以来构造的自动变量之前以及在输入处理程序之前销毁。

    runtime_error 的构造函数是什么 what() 返回一些 strcmp c_str() std::string 作为构造函数参数传递时被销毁, 运行时错误 什么() 可能会返回不同的内容,尽管这是一个有问题的实现,而且它仍然必须是某种以null结尾的字符串,但它不能返回指向过时字符串的指针 一根死绳。

        2
  •  8
  •   anon anon    15 年前

    运行时错误是包含字符串的类。该字符串将由正常C++构造和销毁机制管理。如果它包含char*,那么就必须显式地管理它,但是您仍然不必作为 运行时错误。

    尽管你可以在互联网上看到其他地方,C++被设计成几乎总是做“合理的事情”——你实际上必须努力去打破这个合理的行为,当然,这是不可能的。

        3
  •  3
  •   Terry Mahaffey    15 年前

    请注意,运行时错误异常类生成传递到构造函数的字符串的副本。因此,在对exception对象调用.what()时,返回的字符串实例与传入的字符串实例不完全相同。

    所以为了回答你的问题,你要问的临时问题会在包含它的表达式的“分号”处被销毁(在你的第一个和第二个问题的版本中都是这样),但正如我所说的,这没那么有趣,因为它的副本已经制作好了。