Когда вычисляется выражение throw
, объект исключения инициализируется из значения выражения. Вызываемый объект исключения получает свой тип от статического типа выражения throw, игнорируя любые квалификаторы const
и volatile
. Для типов классов это означает, что copy-initialization выполняется.
Область объекта исключения находится вне области действия блока, в котором происходит выброс. Думайте об этом, как о живущем в специальной области исключений, расположенной по одну сторону от обычного стека вызовов, где живут локальные объекты.
Внутри блока catch
имя, инициализированное с объектом перехваченного исключения, инициализируется с этим объектом исключения, а не с аргументом throw
, даже если это было lvalue.
Если вы catch
через неконстантную ссылку, то вы можете изменить объект исключения, но не то, с чего он был инициализирован. Вы можете изменить поведение программы, если вы повторно сгенерируете исключение способами, которые вы не смогли бы сделать, если поймали по значению или константной ссылке (const_cast
s в стороне).
Объект исключения уничтожается, когда завершается последний блок перехвата, который не выходит с помощью повторного выброса (то есть оценки выражения броска без параметров).