Como lançar uma exceção do C ++

Eu tenho uma compreensão muito pobre de exception handling (ou seja, como personalizar throw, tente, pegar instruções para meus próprios propósitos).

Por exemplo, eu defini uma function da seguinte forma: int compare(int a, int b){...}

Eu gostaria que a function lance uma exceção com alguma mensagem quando a ou b é negativo.

Como devo abordar isso na definição da function?

Simples:

 #include  int compare( int a, int b ) { if ( a < 0 || b < 0 ) { throw std::invalid_argument( "received negative value" ); } } 

A Biblioteca Padrão vem com uma bela coleção de objects de exceção incorporados que você pode lançar. Tenha em mente que você deve sempre jogar por valor e pegar por referência:

 try { compare( -1, 3 ); } catch( const std::invalid_argument& e ) { // do stuff with exception... } 

Você pode ter várias instruções catch () após cada tentativa, para que você possa manipular diferentes tipos de exceção separadamente, se desejar.

Você também pode lançar novamente exceções:

 catch( const std::invalid_argument& e ) { // do something // let someone higher up the call stack handle it if they want throw; } 

E para pegar exceções, independentemente do tipo:

 catch( ... ) { }; 

Basta adicionar o throw onde for necessário e try bloquear o chamador que lida com o erro. Por convenção, você deve apenas lançar coisas que derivam de std::exception , então inclua primeiro.

 int compare(int a, int b) { if (a < 0 || b < 0) { throw std::invalid_argument("a or b negative"); } } void foo() { try { compare(-1, 0); } catch (const std::invalid_argument& e) { // ... } } 

Além disso, olhe em Boost.Exception .

Embora essa questão seja bastante antiga e já tenha sido respondida, eu só quero adicionar uma nota sobre como fazer o tratamento de exceções apropriado no C ++ 11:

Use std::nested_exception e std::throw_with_nested

Ele está descrito no StackOverflow aqui e aqui , como você pode obter um backtrace em suas exceções dentro do seu código sem necessidade de um depurador ou log incômodo, simplesmente escrevendo um manipulador de exceção apropriado que irá retroceder exceções aninhadas.

Como você pode fazer isso com qualquer class de exceção derivada, você pode adicionar muitas informações a tal backtrace! Você também pode dar uma olhada no meu MWE no GitHub , onde um backtrace seria algo como isto:

 Library API: Exception caught in function 'api_function' Backtrace: ~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed ~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt" 

Você pode definir uma mensagem para lançar quando um determinado erro ocorrer:

 throw std::invalid_argument( "received negative value" ); 

ou você pode defini-lo assim:

 std::runtime_error greatScott("Great Scott!"); double getEnergySync(int year) { if (year == 1955 || year == 1885) throw greatScott; return 1.21e9; } 

Normalmente, você teria um bloco try ... catch assim:

 try { // do something that causes an exception }catch (std::exception& e){ std::cerr << "exception: " << e.what() << std::endl; }