Проблема броска и отлова пользовательских исключений в C ++ - PullRequest
1 голос
/ 13 июня 2011

Я создал класс Someting , который выдает исключение SomethingException (SomethingException наследуется от std :: exception), когда не удается создать экземпляр. проблема в том, что я не могу поймать SomethingException как таковой (мне пришлось сделать грязный трюк, чтобы поймать его).

В программе есть место, где она выполняется: Это не работает , исключение не перехватывается и происходит сбой программы.

try{
    Something* s = new Something();
}
catch (SomethingException* e){
    std::cerr<<e.what();
}

В отличие от этого работает (исключение перехватывается и отображается правильное сообщение), но у меня действительно есть ощущение, что я не должен этого делать

try{
    Something* s = new Something();
}
catch (std::exception* e){
    SomethingException* e2 = (SomethingException*) e;
    std::cerr<<e.what();
}

Поскольку указатель приведен в порядок, я могу выполнить эту работу только тогда и только тогда, когда выдается исключение одного типа. В тот момент, когда мне нужно ловить различные типы, это не сработает.

Есть ли способ отловить пользовательское исключение более правильным способом?

Edit:

Исключение выдается следующим образом

//...
throw new SomethingException ("Errormessage"); //Custom exception constructor
//...

Объявление Something :: Something () равно

Something::Something() throw(...)

Использование декларации

Something::Something() throw(SomethingException)
//or
Something::Something() throw(SomethingException*)

Выдает много предупреждений (Предупреждение C4290)

Ответы [ 3 ]

7 голосов
/ 13 июня 2011

В общем случае лучше генерировать исключения по значению и перехватывать их по ссылке:

try {

    throw SomethingException();

} catch (const SomethingException& error) {

    std::cerr << error.what() << '\n';

}

Вы могли бы поймать исключение только с catch (SomethingException*), если бы вы бросили его с throw new SomethingException(). В вашем вопросе недостаточно информации, чтобы сказать, но проблема может быть в том, как SomethingException происходит от std::exception. Проверьте это или измените его для наследования, скажем, от std::runtime_error или std::logic_error.

Кроме того, не используйте throw спецификаторы. Просто не надо. Ни один компилятор не дает никаких преимуществ в использовании проверенных исключений: в действительности, проверенные исключения не проверяются , за исключением случаев ужасного сбоя (бросая std::bad_exception) в случае исключения, которое не соответствует спецификатору. Это, вероятно, то, что происходит в вашем коде.

6 голосов
/ 22 марта 2014

Для тех, у кого может быть проблема, когда пользовательское исключение, производное от std :: exception, генерируется, но не перехватывается, также проверьте: - что наследство является публичным - Если ваше исключение объявлено в другой DLL, то этот класс исключения экспортируется из DLL. Как ни странно, если это не так, это не приводит к ошибке связи (в VS2012), просто не может быть перехвачено.

1 голос
/ 13 июня 2011

Можете ли вы показать код, где вы выбросили исключение.

Еще один момент касается спецификаций броска - это вообще плохая идея.Проблема в том, что C ++, в отличие от Java, не настаивает на throw-спецификациях, поэтому вы не получаете от них никакой выгоды.Все, что они могут сделать, это потенциально вызвать дамп ядра, если ваш код (или некоторый код, который вы вызываете) выдает исключение, которое не указано в throw-spec

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...