Eu tenho um entendimento muito ruim do tratamento de exceções (ou seja, como personalizar instruções de throw, try, catch para meus próprios propósitos).
Por exemplo, eu defini uma função da seguinte maneira: int compare(int a, int b){...}
Eu gostaria que a função gerasse uma exceção com alguma mensagem quando a ou b for negativo.
Como devo abordar isso na definição da função?
c++
exception-handling
Terry Li
fonte
fonte
unsigned int
como os parâmetros em sua assinatura de função. Por outro lado, sou da escola que você só deve lançar e capturar exceções para coisas que são realmente excepcionais.throw()
especificações de exceção em funções.Respostas:
Simples:
A Biblioteca padrão vem com uma bela coleção de objetos de exceção internos que você pode lançar. Lembre-se de que você deve sempre jogar por valor e pegar por referência:
Você pode ter várias instruções catch () após cada tentativa, para poder manipular diferentes tipos de exceção separadamente, se desejar.
Você também pode relançar exceções:
E para capturar exceções, independentemente do tipo:
fonte
throw;
repetia a reprodução com um simples (repetindo o objeto original e preservando seu tipo) em vez dethrow e;
(jogando uma cópia do objeto capturado, possivelmente alterando seu tipo).Basta adicionar
throw
onde for necessário etry
bloquear no chamador que lida com o erro. Por convenção, você só deve jogar coisas que derivamstd::exception
; portanto, inclua<stdexcept>
primeiro.Além disso, consulte o Boost.Exception .
fonte
Embora essa pergunta seja bastante antiga e já tenha sido respondida, só quero adicionar uma observação sobre como lidar com exceções no C ++ 11:
Use
std::nested_exception
estd::throw_with_nested
É descrito no StackOverflow aqui e aqui , como você pode obter um retorno das suas exceções dentro do seu código sem a necessidade de um depurador ou log complicado, simplesmente escrevendo um manipulador de exceções adequado que irá repetir exceções aninhadas.
Como você pode fazer isso com qualquer classe de exceção derivada, você pode adicionar muitas informações a esse backtrace! Você também pode dar uma olhada no meu MWE no GitHub , onde um backtrace seria algo como isto:
fonte
Você pode definir uma mensagem a ser lançada quando ocorrer um determinado erro:
ou você pode defini-lo assim:
Normalmente, você teria um
try ... catch
bloco como este:fonte
Queria ADD para as outras respostas aqui descritas uma nota adicional, no caso de exceções personalizadas .
No caso em que você cria sua própria exceção personalizada, que deriva de
std::exception
, quando você captura os tipos de exceções "todos os possíveis", sempre deve iniciar ascatch
cláusulas com o tipo de exceção "mais derivado" que pode ser capturado. Veja o exemplo (do que NÃO fazer):NOTA:
0) A ordem correta deve ser vice-versa, ou seja, primeiro você
catch (const MyException& e)
é seguido porcatch (const std::exception& e)
.1) Como você pode ver, quando você executa o programa como está, a primeira cláusula catch será executada (o que provavelmente é o que você NÃO queria em primeiro lugar).
2) Embora o tipo capturado na primeira cláusula catch seja do tipo
std::exception
, a versão "adequada"what()
será chamada - porque é capturada por referência (altere pelo menos ostd::exception
tipo de argumento capturado por valor - e você experimentará o fenômenos de "corte de objetos" em ação).3) Caso o "algum código devido ao fato de a exceção XXX ter sido lançada ..." faça coisas importantes COM RESPEITO ao tipo de exceção, há um mau comportamento do seu código aqui.
4) Isso também é relevante se os objetos capturados forem objetos "normais" como:
class Base{};
eclass Derived : public Base {}
...5)
g++ 7.3.0
no Ubuntu 18.04.1 produz um aviso que indica o problema mencionado:Mais uma vez , eu vou dizer, que esta resposta é apenas para ADD para as outras respostas aqui descritas (Eu pensei que este ponto vale a pena mencionar, ainda não poderia representá-lo dentro de um comentário).
fonte