2016-09-16 1 views
1

Для приведенного ниже кода результатом является «EA Exception Finished», что означает, что мы выбрали производный класс, который он поймал базовым классом. Это всегда? И если да, то как я могу сделать уловы производного класса, таким образом появляется «EB Exception Finished»?Зачем бросать на уловы производного класса по базе?

Также я не могу точно понять, что это означает: throw EB() и catch(EA&). И делает catch(EA&) означает, что блок catch получает ссылку для EA объект?

Извините за мое невежество. Если вы порекомендуете мне книгу или что-то, чтобы ссылаться на структуру исключений, это будет большой помощью.

class EA {}; 
class EB: public EA {}; 

void F() 
{ 
    throw EB(); // throw at EB(). 
} 

int main() 
{ 
    try 
    { 
    F(); 
    } 
    catch(EA&) // caught here?? 
    { 
    std::cout<<"EA Exception"; 
    } 
    catch(EB&) // why not me? every time? 
    { 
    std::cout<<"EB Exception"; 
    } 

    std::cout<<" Finished"<<std::endl; 

    return 0; 
} 
+1

Исключение всегда попадает в блок * catch * *, который * может * поймать его, поэтому ваш заказ неверен. –

+0

Большое спасибо за ваш ответ !!! –

ответ

1

Причина:

Приведение к базовому типу

производного класса к основанию. и, следовательно, всегда застревает в первом улове.

+0

Спасибо !!!!!!!!! –

1

Потому что блоки блокировки проверяют порядок, который вы их объявляете.

вы сначала поймаете EA&. EB получен из EA, поэтому это действительный catch, а второй catch игнорируется.

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

+0

Спасибо большое! Таким образом, бросок в производный класс может быть также пойман базовым классом, но он нежелателен, потому что он не может быть специализированным лечением? –

+0

Это можно сделать, если вы измените порядок блока «catch». Также, как упоминалось в другом ответе. Вы должны получать предупреждения в этих случаях. – Hayt

+0

Большое спасибо !!!! –

1

отчеты об уловах проверяются в порядке. EA& подходит, поэтому он используется. EB& никогда не может быть сопоставлен. Сначала вам нужно поставить более конкретный улов.

catch(EB&) // Will catch 
    { 
    std::cout<<"EB Exception"; 
    } 
    catch(EA&) // and this would catch EA objects that aren't EB. 
    { 
    std::cout<<"EA Exception"; 
    } 
+0

Спасибо большое!Тогда EB улавливает сначала, а затем EA также ловят поэтому? –

+1

№ Выполняется только первый соответствующий блок catch. довольно часто имеется блок catch для конкретного исключения, для 'const std :: exception &' и для '...'. Каждая печать последовательно менее детальной информации. –

+0

Большое вам спасибо за ваш исчерпывающий ответ !!! –

3

Изменить порядок catch блоков, чтобы исправить это поведение:

#include <iostream> 

class EA {}; 
class EB: public EA {}; 

void F() 
{ 
    throw EB(); // throw at EB(). 
} 

int main() 
{ 
    try 
    { 
    F(); 
    } 
    catch(EB&) // why not me? every time? 
    { 
    std::cout<<"EB Exception"; 
    } 
    catch(EA&) // caught here?? 
    { 
    std::cout<<"EA Exception"; 
    } 

    std::cout<<" Finished"<<std::endl; 

    return 0; 
} 

Компилятор даже предупреждает вас об этом:

main.cpp:21:3: warning: exception of type 'EB' will be caught 
    catch(EB&) // why not me? every time? 
    ^~~~~ 
main.cpp:17:3: warning: by earlier handler for 'EA' 
    catch(EA&) // caught here?? 
    ^~~~~ 
+0

Спасибо большое! Что это означает, бросив EB() в этом контексте? Какой компилятор вы используете? –

+0

@ DongkyuChoi Я использовал GCC в [coliru] (http://coliru.stacked-crooked.com/a/33ca04ff57d31fa6) –

+0

Большое спасибо за ваш ответ! –

2

Как упомянуто стандартом в [except.handle] (рабочий проект):

Обработчики для блока try проверяются по внешнему виду. Это позволяет писать обработчики, которые никогда не могут быть выполнены, например, путем размещения обработчика для производного класса после обработчика соответствующего базового класса.

Это именно то, что вы сделали. Интересно, действительно.
Инвертировать обработчики для решения проблемы.

+0

Большое спасибо !!! –