2017-02-07 3 views
1

Я перебежать проблема кодирования, что у меня возникают проблемы с пониманием (обратите внимание на строку с меткой // -):Классы и обработка исключений в C++

#include <iostream> 

using namespace std; 

class X { }; 

class X0 { }; 
class X1: public X0 { }; 
class X2: public X1 { }; 

void f(int i) { 
    if (i == 0) { 
     throw X0(); 
    } else if (i == 1) { 
     throw X1(); 
    } else if (i == 2) { 
     throw X2(); 
    } else { 
     throw X(); 
    } 
} 

int main(int argc, char* argv[]) { 
    try { 
     f(0);      //- 
    } catch (X1) { 
     cout << "A" << endl; 
    } catch (X2) { 
     cout << "B" << endl; 
    } catch (X0) { 
     cout << "C" << endl; 
    } catch (...) { 
     cout << "D" << endl; 
    } 
} 

Выход этого кода C, как и ожидалось. Если я изменю помеченную строку на "f (1);" выход A, также как и ожидалось.

Однако, если я поменяю помеченную строку на "f (2);" ответ также A, и я не понимаю, почему. Я чувствую, что это может иметь какое-то отношение к сфере действия деструкторов, но мои попытки найти информацию об этом не были успешными, потому что я не совсем уверен, что изучать. Кто-нибудь сможет объяснить, что здесь происходит, или просто название концепции, эта проблема иллюстрирует, чтобы я мог ее исследовать? Любая помощь приветствуется.

+1

X2 также является X1, и захват для X1 является первым, поэтому он запускается. – Vality

+1

Какие деструкторы? Здесь нет деструкторов. – EJP

+0

И что вы подразумеваете под «областью деструкторов»? – EJP

ответ

3

An X2 наследует от X1 и так «является» X1 и подвох блок для X1 является первым, так спусковые прежде чем мы достигнем X2 один.

+0

О, я вижу, так это демонстрация наследования? – Mock

+0

@Mock Именно поэтому я всегда говорю, что наследование - это (как правило) отношение «есть». Почти в каждом случае, если B является дочерним элементом A, код будет действовать так, как если бы B "был" и A и рассматривать его как один, если он необходим. – Vality

+0

Хорошо, это имеет смысл, прошло очень много времени с тех пор, как я изучил наследование. Спасибо, что помогли всем, я буду одобрять это, когда это возможно. – Mock

1

Вы должны поймать X2 перед тем X1, как это происходит от X1, в противном случае улов X1 уловов X2, а также.

В Java это было бы ошибкой компиляции.

3

Когда i == 2, вы бросаете X2, X2 получается из X1.

Порядок уловов имеет значение, вы пытаетесь поймать X1 первым, X2 (то, что вы бросили) - это X1, так что это улов, который срабатывает. Вы должны изменить порядок уловы, чтобы поймать наиболее специфичный первый

2

Однако, если я изменю тегированную строку на "f (2);" ответ также А, и я не понимаю, почему.

Это потому, что X2 является подклассом X1.

Когда вы позвоните, f(2) в try, f(2) throws X2. Похоже, что исключение должно быть уловлено в catch(X2). Однако X2 является подклассом X1.

Так исключение ловится в catch(X1) и код внутри catch печатает А.

Так что, если вы хотите увидеть B при вызове f(2), код должен быть.

//skipped some code 

int main(int argc, char* argv[]) { 
    try { 
     f(2);      //- 
    } catch (X2) { 
     cout << "B" << endl; 
    } catch (X1) { 
     cout << "A" << endl; 
    } catch (X0) { 
     cout << "C" << endl; 
    } catch (...) { 
     cout << "D" << endl; 
    } 
} 
Смежные вопросы