Область объекта исключения в C ++ - PullRequest
37 голосов
/ 31 октября 2009

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

Ответы [ 3 ]

35 голосов
/ 31 октября 2009

Когда вычисляется выражение throw, объект исключения инициализируется из значения выражения. Вызываемый объект исключения получает свой тип от статического типа выражения throw, игнорируя любые квалификаторы const и volatile. Для типов классов это означает, что copy-initialization выполняется.

Область объекта исключения находится вне области действия блока, в котором происходит выброс. Думайте об этом, как о живущем в специальной области исключений, расположенной по одну сторону от обычного стека вызовов, где живут локальные объекты.

Внутри блока catch имя, инициализированное с объектом перехваченного исключения, инициализируется с этим объектом исключения, а не с аргументом throw, даже если это было lvalue.

Если вы catch через неконстантную ссылку, то вы можете изменить объект исключения, но не то, с чего он был инициализирован. Вы можете изменить поведение программы, если вы повторно сгенерируете исключение способами, которые вы не смогли бы сделать, если поймали по значению или константной ссылке (const_cast s в стороне).

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

9 голосов
/ 31 октября 2009

Объект исключения доступен только в блоке catch. Вы не можете использовать объект исключения за пределами блока catch. Следующие шаги выполняются, когда вы бросаете исключение и ловите:

try
{
 MyException anObject;
 throw anObject;  //1

}
catch(MyException exObject)
{
}
  • Предложение throw (// 1) получает локальный объект anObject и обрабатывает его как аргумент значения: создается копия anObject.
  • обработчик catch перехватывает объект MyException, который снова является параметром-значением. В этот момент создается еще одна копия.
  • Если обработчик catch был бы реализован так, чтобы получать ссылку на объект (catch (MyException &o)), вторая копия исключается.
  • если обработчик catch получает объект исключения через const&, то вы можете вызывать только методы const.
4 голосов
/ 31 октября 2009

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

...