У нас есть иерархия классов исключений - есть класс GenericException
и несколько классов, которые вытекают из него. GenericException
полиморфный - у него есть виртуальный деструктор.
Один из производных классов FileException
выдается для указания ошибок при манипулировании объектами файловой системы. FileException
имеет GetErrorCode()
метод, который возвращает код, указывающий, что на самом деле пошло не так.
Иерархия уже существует, я не могу ее изменить, поэтому об этом не может быть и речи.
Исключения вызываются из кода, который мы не контролируем, и они всегда генерируются с ключевым словом new , поэтому мы можем перехватить их только по указателю - об этом тоже не может быть и речи.
Теперь у меня есть ситуация, когда набор операторов может генерировать исключение, которое гарантированно будет получено из GenericException
. Если это FileException
и , тип ситуации ошибки - «файл не найден». Я хочу ничего не делать, в противном случае я хочу показать сообщение об ошибке, а затем в любом случае считаю, что исключение обработано.
У меня есть два варианта - любой:
} catch( GenericException* e ) {
FileException* fileException = dynamic_cast<FileException*>( e );
if( fileException == 0 || fileException->GetErrorCode() != FileNotFound ) {
ShowMessage( e );
}
delete e;
}
или этот:
} catch( FileException* e ) {
if( fileException->GetErrorCode() != FileNotFound ) {
ShowMessage( e );
}
delete e;
} catch( GenericException* e ) {
ShowMessage( e );
delete e;
}
Я предпочитаю первый, потому что он уменьшает дублирование кода. Но я слышал мнение, что, поскольку C ++ допускает выборочные блоки catch (как во втором варианте), я не должен использовать dynamic_cast
- выборочные блоки catch для этого не нужны.
Какой вариант лучше? В чем может быть причина не первый вариант здесь?