2016-01-07 2 views
0

Я новичок в C++ (из C) и пишу класс B, который является членом другого класса A.C++ вложенный метод try catch (practices)

Участник B выдает исключение, если родитель пытается получить доступ к данным, которые не существуют из контейнера B (я выбрал исключение invalid_argument). У члена B есть объект, который можно рассматривать как контейнер STL, поэтому он будет для этого примера.

Мой вопрос: если я поймаю исходное исключение invalid_parameter в A, считается ли это хорошей практикой на C++ для повторного выброса одного и того же исключения (я бы повторно выбрал исходную ошибку, но я делаю некоторые записи в ней, так что what() отличается), или я могу просто выбросить std::exception. Мой код теперь имеет много

try { A.calls_b_exception } catch (std::invalid_argument& ie) {...} catch (std::exception& e) {...}

блоков и мне было интересно, если я мог бы свести их к

try { A.calls_b_exception } catch (std::exception& e) {...}

и по-прежнему следовать хорошие C++ парадигм. Пример кода, который похож на мою ситуацию:

class B 
{ 
    std::vector<int> stuff; 

    int get_value(int index) 
    { 
     if (index >= stuff.size()) { 
      stringstream err; 
      err << "--> invalid index " << index << " for stuff"; 
      throw std::invalid_argument(err.str()); 
     } 
    } 
} 

class A 
{ 
    B b; 
    // Assume there are methods to add a bunch of stuff to B 
    int get_value(int index) 
    { 
     try { 
      b.get_value(); 
     } catch (std::invalid_argument& ie) { 
      stringstream err; 
      err << ie.what() << "\n\t--> A::get_value(" << index << ")"; 
      // should I throw the same exception here or is this considered good C++ etiquette? 
      throw std::exception(err.str()); 
     } catch (std::exception& e) { 
      throw; // something I was not anticipating handling happened 
     } 
    } 
} 

int main 
{ 
    A a; 
    // Assume more stuff to add to A 
    try { 
     a.get_value(-1); 
    } 
    catch (std::exception& e) { 
     stringstream err; 
     err << "--> invalid index " << index << " for main"; 
     throw std::exception(err.str());exception here? 
    } 
} 
+1

Typo? Ваш «Я делаю это» и «должен ли я это делать» идентичен. –

+0

В обработчике исключений верхнего уровня вы на самом деле не знаете, где исходит или что может быть, если код в блоке 'try' очень узкий (например, ваш вызов одной функции). Я лично также не поймал бы исключение, если я действительно не обработаю ошибку, просто перетащив ее с более подробным сообщением об ошибке, не «обрабатывает» ошибку, ИМО. –

+0

'Мой код теперь имеет много: try {A.calls_b_exception} catch (std :: invalid_argument и т. Д.) {...} catch (std :: exception & e) {...}'. вам действительно не нужно ловить их, если вы только заходите в систему. 'std :: invalid_argument' наследуется от' std :: exception'. catching 'std :: exception' также поймает' std :: invalid_argument', и вы все равно можете получить доступ к функции what(). 'try {A.calls_b_exception} catch (std :: exception & e) {...}' отлично. – user1810087

ответ

0

Вы не можете создать экземпляр std::exception(std::string), поэтому мой первоначальный подход не будет работать. Спасибо тем, кто взял время, чтобы прочитать мой вопрос и помочь мне.