Пространства имён
Варианты
Действия

Блок-try-функции

Материал из cppreference.com
< cpp‎ | language
 
 
 
 

Устанавливает обработчик исключений вокруг тела функции.

Содержание

[править] Синтаксис

Блок-try-функции это одна из альтернативных форм синтаксиса для тела-функции, которая является частью определение функции.

try инициализатор-конструктора (необязательно) составное-выражение последовательность-обработчиков
инициализатор-конструктора список инициализаторов элементов, разрешённый только в конструкторах
составное-выражение заключённая в фигурные скобки последовательность операторов, составляющая тело функции
последовательность-обработчиков последовательность из одного или нескольких предложений catch

[править] Объяснение

Блок-try-функции связывает последовательность предложений catch со всем телом функции, а также со списком инициализаторов элементов (если используется в конструкторе). Каждое исключение, брошенное из любого оператора в теле функции, или (для конструкторов) из любого элемента или базового конструктора, или (для деструкторов) из любого элемента или базового деструктора, передаёт управление последовательности-обработчиков так же, как исключение, брошенное в обычном блоке try.

#include <iostream>
#include <string>
 
struct S
{
    std::string m;
 
    S(const std::string& str, int idx) try : m(str, idx)
    {
        std::cout << "S(" << str << ", " << idx << ") построен, m = " << m << '\n';
    }
    catch(const std::exception& e)
    {
        std::cout << "S(" << str << ", " << idx << ") потерпел крах: " << e.what() << '\n';
    } // здесь неявный "throw;" для конструктора
};
 
int main()
{
    S s1{"ABC", 1}; // не бросает (индекс в пределах допустимого)
 
    try
    {
        S s2{"ABC", 4}; // бросает (выход за границы)
    }
    catch (std::exception& e)
    {
        std::cout << "S s2... вызывает исключение: " << e.what() << '\n';
    }
}

Прежде чем будут введены какие-либо предложения catch блока-try-функции в конструкторе, все полностью сконструированные элементы и базовые классы уже будут уничтожены.

Если блок-try-функции находится в конструкторе делегирования, который вызвал конструктор без делегирования, который завершился успешно, но затем тело конструктора делегирования вызывает исключение, деструктор этого объекта будет завершён до любых предложений catch блока-try-функции.

(начиная с C++11)

Прежде чем будут введены какие-либо предложения catch блока-try-функции в деструкторе, все базовые и невариантные элементы уже будут уничтожены.

Поведение не определено, если предложение catch блока-try-функции, используемого в конструкторе или деструкторе, обращается к базовому классу или нестатическому элементу объекта.

Каждое предложение catch в блоке-try-функции для конструктора должно завершаться выдачей исключения. Если управление достигает конца такого обработчика, текущее исключение автоматически выбрасывается снова, как будто через throw;. Оператор return не допускается ни в одном предложении catch блока-try-функции кон��труктора.

Достижение конца предложения catch для блока-try-функции в деструкторе также автоматически повторно выдаёт текущее исключение, как будто с помощью throw;, но допускается оператор return.

Для всех других функций достижение конца предложения catch эквивалентно return;, если возвращаемый тип функции (возможно, cv-квалифицированный) void, иначе поведение не определено.

[править] Примечание

Основная цель блоков-try-функций состоит в том, чтобы реагировать на исключение, созданное из списка инициализаторов элементов в конструкторе, путём регистрации и повторного создания, изменения объекта исключения и повторного создания, создания вместо него другого исключения или завершения программы. Они редко используются с деструкторами или с обычными функциями.

Блок-try-функции не перехватывает исключения, генерируемые конструкторами копирования/перемещения и деструкторами параметров функции, передаваемых по значению: эти исключения генерируются в контексте вызывающего объекта.

Блок-try-функции верхнего уровня потока не перехватывает исключения, генерируемые конструкторами и деструкторами локальных объектов потока (за исключением конструкторов локальных объектов потока в области видимости функции). (начиная с C++11)

Аналогично, блок-try-функции main() не перехватывает исключения, генерируемые конструкторами и деструкторами статических объектов (за исключением конструкторов статических локальных объектов функции).

Область видимости и время жизни параметров функции (но не любых объектов, объявленных в самой функции), распространяются до конца последовательности-обработчиков.

int f(int n = 2) try
{
    ++n; // инкрементирует параметр функции
    throw n;
}
catch(...)
{
    ++n; // n находится в области видимости и по-прежнему ссылается на параметр функции
    assert(n == 4);
    return n;
}

[править] Отчёты о дефектах

Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:

Номер Применён Поведение в стандарте Корректное поведение
CWG 1167 C++98 не было указано, будет ли блок-try-функции в деструкторе
перехватывать исключения из базового деструктора или
деструктора-элемента
такие исключения перехватываются