Когда вы бросаете объект, копия этого объекта создается в каком-то другом месте, поэтому раскрутка стека может продолжаться, и копия может быть передана в обработчик исключений (либо по ссылке, поэтому дальнейшие копии не создаются, либо по значению, создающему второй экземпляр).
Вы можете убедиться, что копия сделана, если исключение не подлежит копированию. Вы больше не сможете бросать объекты этого типа.
Когда реализация копирует объект, который вы бросаете, она смотрит на статический тип выражения, а не на динамический тип. Это означает, что в вашем коде он видит, что вы выбрасываете Exception
, и поэтому полученная копия является примером нарезки (т.е. вместо копирования всего объекта, только подобъекта базового класса копируется).
Вы можете избежать среза, если убедитесь, что статический тип выражения броска совпадает с типом завершенного объекта, что можно сделать, просто не устанавливая тип в Exception
.
Это должно вывести «catch: IllegalArgumentException».
try
{
IllegalArgumentException i;
throw i;
}
catch(Exception& e)
{
cout << "caught: ";
e.print();
}