Какова область действия объекта исключения в С++? выходит ли он из области действия, как только выполняется обработчик улова? Кроме того, если я создаю объект неназванного исключения и выкидываю его, то, поймав это исключение, имеет значение, если я поймаю его с помощью ссылки на константу или неконстантной ссылки?
Область действия объекта исключения в С++
Ответ 1
Когда выражение throw
оценивается, объект исключения инициализируется из значения выражения. Выделенный объект исключения получает свой тип от статического типа выражения throw, игнорируя любые квалификаторы const
и volatile
. Для типов классов это означает, что выполняется инициализация копирования.
Объект объекта исключений выходит за пределы области, в которой происходит бросок. Подумайте об этом как о проживании в специальной зоне исключения на одной стороне обычного стека вызовов, где живут локальные объекты.
Внутри блока catch
имя, инициализированное зараженным объектом исключения, инициализируется этим объектом исключения, а не аргументом throw
, даже если это значение было lvalue.
Если вы catch
через не-const ссылку, вы можете мутировать объект исключения, но не то, из чего оно было инициализировано. Вы можете изменить поведение программы, если вы повторно выбрали исключение способами, которые вы не смогли бы, если бы вы поймали по значению или константной ссылке (const_cast
в сторону).
Объект исключения уничтожается, когда завершается последний блок catch, который не выходит через повторный бросок (т.е. безразличное выражение экспрессии броска).
Ответ 2
Объект исключения доступен только в блоке catch
. Вы не можете использовать объект исключения вне блока catch
. Следующие шаги происходят, когда вы бросаете исключение и catch:
try
{
MyException anObject;
throw anObject; //1
}
catch(MyException exObject)
{
}
- Предложение
throw
(//1) получает локальный объектanObject
и рассматривает его как аргумент значения: он создает копиюanObject
. - обработчик
catch
ловит объект MyException, который снова является параметром значения. В этот момент создается другая копия. - Если обработчик
catch
был бы реализован так, чтобы получить ссылку на объект(catch (MyException &o))
, то вторая копия будет устранена. - Если
catch
обработчик получает объект исключения с помощьюconst&
, тогда вы можете вызывать только методыconst
.
Ответ 3
Прежде всего, объект, который вы бросаете, выходит из сферы действия почти сразу. То, что поймают обработчики исключений, - это копия исходного объекта. Эта копия будет удалена после выполнения обработчика захвата, если вы не поймаете его по значению (не по ссылке). В этом случае будет создана другая копия. Но вы должны поймать его по ссылке (предпочтительно, const one) в любом случае.