5

考虑以下代码:

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

// ...

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

传递给 runtime_error 的字符串是 string 的临时返回的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());

现在operator+返回的临时字符串什么时候被销毁了?它会在 catch 块尝试打印它之前被销毁吗,这就是为什么 runtime_error 接受 std::string 而不是 const char* 的原因吗?

4

3 回答 3

8

runtime_error 是一个包含字符串的类。该字符串将由正常的 C++ 构造和销毁机制为您管理。如果它包含一个 char *,那么它必须被显式管理,但作为runtime_error的用户,您仍然不需要做任何事情。

尽管您可能在 Internet 上的其他地方看到了什么,但 C++ 被设计为几乎总是做“合理的事情”——您实际上必须相当努力地尝试打破这种合理的行为,当然这并非不可能。

于 2010-03-10T11:01:14.403 回答
5

As a temporary object (12.2), the result of the + will be destroyed as the last step in the evaluation of the full-expression (1.9/9) that contains it. In this case the full-expression is the throw-expression.

A throw-expression constructs a temporary object (the exception-object) (15.1) (std::runtime_error in this case). All the temporaries in the throw-expression will be destroyed after the exception-object has been constructed. The exception is thrown only once the evaluation of the throw-expression has completed, as the destruction of temporaries is part of this evaluation they will be destroyed before the destruction of automatic variables constructed since the try block was entered (15.2) and before the handler is entered.

runtime_error的构造函数的后置条件是what()返回的东西strcmp被认为等于c_str()传入的参数返回的东西。理论上的可能性是,一旦std::string作为构造函数参数传递的参数被破坏,runtime_error'swhat()可能会返回不同的东西,尽管这将是一个有问题的实现,并且它仍然必须是某种以 null 结尾的字符串,但它不能返回一个指向失效c_str()字符串的指针。

于 2010-03-10T11:22:00.083 回答
3

请注意,runtime_error 异常类会复制传递给构造函数的字符串。因此,当您在异常对象上调用 .what() 时,您不会返回您传入的完全相同的字符串实例。

So to answer your question, the temporary you're asking about gets destroyed "at the semicolon" of the expression that contains it (this is true in both your first and second version of the question), but as I said, this isn't that interesting, because a copy of it was already made.

于 2010-03-10T11:21:40.693 回答