Область действия объекта исключения в С++

Какова область действия объекта исключения в С++? выходит ли он из области действия, как только выполняется обработчик улова? Кроме того, если я создаю объект неназванного исключения и выкидываю его, то, поймав это исключение, имеет значение, если я поймаю его с помощью ссылки на константу или неконстантной ссылки?

Ответ 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) в любом случае.