Ao projetar minha primeira biblioteca C ++ 'séria', estou me perguntando:
É bom estilo derivar exceções std::exception
e seus descendentes ?!
Mesmo depois de ler
- Projetando classes de exceção
- O que é um 'bom número' de exceções a serem implementadas na minha biblioteca?
Ainda não tenho certeza. Porque, além da prática comum (mas talvez não seja boa), eu assumiria, como usuário da biblioteca, que uma função da biblioteca lançaria std::exception
s somente quando as funções da biblioteca padrão falharem na implementação da biblioteca, e não poderá fazer nada a respeito. Mas ainda assim, ao escrever o código do aplicativo, para mim é muito conveniente, e também IMHO de boa aparência apenas para lançar um std::runtime_error
. Além disso, meus usuários também podem confiar na interface mínima definida, como what()
códigos ou.
E, por exemplo, meu usuário fornece argumentos defeituosos, o que seria mais conveniente do que lançar um std::invalid_argument
, não? Então, combinado com o uso ainda comum de std :: exception que vejo nos outros códigos: Por que não ir ainda mais longe e derivar de sua classe de exceção personalizada (por exemplo, lib_foo_exception) e também de std::exception
.
Pensamentos?
lib_foo_exception
classe deriva std::exception
, o usuário da biblioteca capturaria lib_foo_exception
apenas capturando std::exception
, além de quando capturas apenas a biblioteca. Então, eu também poderia perguntar se minha classe raiz de exceção da biblioteca deve herdar de std :: exception .
lib_foo_exception
?" Com a herança de std::exception
você pode fazê-lo por catch(std::exception)
OU por catch(lib_foo_exception)
. Sem derivar std::exception
, você o capturaria se e somente se , por catch(lib_foo_exception)
.
catch(...)
. Está lá porque a linguagem permite o caso que você está considerando (e para "comportar-se mal" nas bibliotecas), mas isso não é uma prática recomendada moderna.
catch
sites mais gerais e mais grossos, além de transações mais grossas que modelam uma operação final do usuário. Se você compará-lo a idiomas que não promovem a idéia de captura generalizada std::exception&
, por exemplo, eles geralmente têm muito mais código com try/catch
blocos intermediários preocupados com erros muito específicos, o que diminui um pouco a generalidade do tratamento de exceções quando ele começa a aparecer. uma ênfase muito mais forte no tratamento manual de erros e também em todos os erros díspares que poderiam ocorrer.
std::exception
não significa que você jogou astd::exception
. Além disso,std::runtime_error
herda destd::exception
em primeiro lugar, e owhat()
método vem destd::exception
, nãostd::runtime_error
. E você definitivamente deve criar suas próprias classes de exceção em vez de lançar exceções genéricas comostd::runtime_error
.