Разрушение строковых временных файлов в вызванных исключительных ситуациях

Рассмотрите следующий код:

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 принимает станд.:: строка и не символ константы*?

5
задан AshleysBrain 30 April 2010 в 13:07
поделиться

3 ответа

В качестве временного объекта (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 () мертвой строки.

5
ответ дан 18 December 2019 в 10:44
поделиться

runtime_error - это класс, содержащий строку. Эта строка будет управляться за вас обычными механизмами построения и уничтожения C ++. Если бы он содержал char *, то этим нужно было бы явно управлять, но вам все равно не нужно было бы ничего делать как пользователь runtime_error.

Несмотря на то, что вы можете прочитать в другом месте в Интернете, C ++ разработан, чтобы почти всегда делать «разумные вещи» - на самом деле вам нужно довольно сильно постараться, чтобы нарушить это разумное поведение, хотя, конечно, это возможно.

8
ответ дан 18 December 2019 в 10:44
поделиться

Обратите внимание, что класс исключения runtime_error создает копию строки, переданной в конструктор. Поэтому, когда вы вызываете .what () для объекта исключения, вы не получаете тот же самый точный экземпляр строки, который вы передали.

Итак, чтобы ответить на ваш вопрос, временное, о котором вы спрашиваете, уничтожается "на точка с запятой в выражении, которое его содержит (это верно как для вашей первой, так и для второй версии вопроса), но, как я уже сказал, это не так уж интересно, потому что его копия уже была сделана.

3
ответ дан 18 December 2019 в 10:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: