繁体   English   中英

在抛出异常时破坏弦乐临时演员

[英]Destruction of string temporaries in thrown exceptions

请考虑以下代码:

std::string my_error_string = "Some error message";

// ...

throw std::runtime_error(std::string("Error: ") + my_error_string);

传递给runtime_error的字符串是字符串的operator+返回的临时字符。 假设此异常的处理方式如下:

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

字符串的operator+返回的临时值何时被销毁? 语言规范有什么可说的吗? 另外,假设runtime_error接受了一个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块尝试打印之前被销毁,这就是为什么runtime_error接受std :: string而不是const char *?

runtime_error是一个包含字符串的类。 该字符串将由普通的C ++构造和销毁机制为您管理。 如果它包含char *,则必须显式管理,但您仍然不必作为runtime_error的用户执行任何操作

尽管你可能在互联网上的其他地方读到了什么,但C ++的设计几乎总是做“合理的事情” - 你实际上必须非常努力地打破这种合理的行为,当然这并非不可能。

作为临时对象(12.2), +的结果将作为评估包含它的全表达式 (1.9 / 9)的最后一步被销毁。 在这种情况下, full-expressionthrow-expression

throw-expression构造一个临时对象( 异常对象 )(15.1)(在本例中为std::runtime_error )。 在构造了异常对象之后, throw-expression中的所有临时值都将被销毁。 抛出表达式的评估完成后抛出异常,因为临时的破坏是此评估的一部分,它们将在自输入try块(15.2)之后和处理程序之前构造的自动变量销毁之前被销毁进入。

runtime_error的构造函数的后置条件是what()返回strcmp认为等于传入的参数返回的c_str()内容。 这是一个理论上的可能性,一旦作为构造函数参数传递的std::string被销毁, runtime_errorwhat()可以返回不同的东西,虽然它将是一个有问题的实现,它仍然必须是一个以null结尾的字符串某种形式,它无法返回指向死字符串陈旧c_str()的指针。

请注意,runtime_error异常类生成传递给构造函数的字符串的副本。 因此,当您在异常对象上调用.what()时,您无法返回传入的相同的字符串实例。

所以为了回答你的问题,你所询问的临时内容会在包含它的表达式的“分号”处被破坏(这在你的第一个和第二个版本的问题中都是如此),但正如我所说,这不是'这很有趣,因为它的副本已经制作完成了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM