Рассмотрите следующий код:
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 взял a 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());
Теперь, когда временная строка возвращается оператором + уничтоженный? Был бы это быть уничтоженным, прежде чем блок выгоды попытается распечатать его и будет этим, почему runtime_error принимает станд.:: строка и не символ константы*?
В качестве временного объекта (12.2) результат +
будет уничтожен на последнем этапе оценки полное выражение (1.9 / 9), которое его содержит. В этом случае полное выражение - это throw-выражение .
throw-expression создает временный объект (объект-исключение ) (15.1) ( std :: runtime_error
в данном случае). Все временные объекты в выражении выброса будут уничтожены после создания объекта исключения . Исключение генерируется только после завершения вычисления throw-expression , поскольку уничтожение временных файлов является частью этой оценки, они будут уничтожены до уничтожения автоматических переменных, созданных с момента входа в блок try ( 15.2) и до того, как будет введен проводник.
Пост-условие для конструктора runtime_error
состоит в том, что what ()
возвращает то, что strcmp
считает равным тому, что c_str ()
при возврате переданного аргумента. Теоретически возможно, что после уничтожения std :: string
, переданного в качестве аргумента конструктора, runtime_error
what ()
может вернуть что-то другое, хотя это была бы сомнительная реализация, и это все равно должна была бы быть какая-то строка с завершающим нулем, она не могла бы вернуть указатель на устаревшую c_str ()
мертвой строки.
runtime_error - это класс, содержащий строку. Эта строка будет управляться за вас обычными механизмами построения и уничтожения C ++. Если бы он содержал char *, то этим нужно было бы явно управлять, но вам все равно не нужно было бы ничего делать как пользователь runtime_error.
Несмотря на то, что вы можете прочитать в другом месте в Интернете, C ++ разработан, чтобы почти всегда делать «разумные вещи» - на самом деле вам нужно довольно сильно постараться, чтобы нарушить это разумное поведение, хотя, конечно, это возможно.
Обратите внимание, что класс исключения runtime_error создает копию строки, переданной в конструктор. Поэтому, когда вы вызываете .what () для объекта исключения, вы не получаете тот же самый точный экземпляр строки, который вы передали.
Итак, чтобы ответить на ваш вопрос, временное, о котором вы спрашиваете, уничтожается "на точка с запятой в выражении, которое его содержит (это верно как для вашей первой, так и для второй версии вопроса), но, как я уже сказал, это не так уж интересно, потому что его копия уже была сделана.