Penso que todas as respostas que explicam que você não deve ter uma bandeira que controla se uma exceção é lançada ou não são boas. O conselho deles seria o meu conselho para quem sente a necessidade de fazer essa pergunta.
No entanto, gostaria de salientar que há uma exceção significativa a essa regra. Quando você tiver avançado o suficiente para começar a desenvolver APIs que centenas de outras pessoas usarão, há casos em que você pode querer fornecer esse sinalizador. Quando você está escrevendo uma API, não está apenas escrevendo para os puristas. Você está escrevendo para clientes reais que têm desejos reais. Parte do seu trabalho é fazê-los felizes com sua API. Isso se torna um problema social, e não um problema de programação, e às vezes os problemas sociais ditam soluções que seriam menos do que ideais como soluções de programação por conta própria.
Você pode achar que possui dois usuários distintos da sua API, um dos quais deseja exceções e outro que não. Um exemplo da vida real onde isso pode ocorrer é com uma biblioteca usada tanto no desenvolvimento quanto em um sistema incorporado. Em ambientes de desenvolvimento, os usuários provavelmente vão querer ter exceções em todos os lugares. Exceções são muito populares para lidar com situações inesperadas. No entanto, eles são proibidos em muitas situações incorporadas porque são muito difíceis de analisar restrições em tempo real. Quando você realmente se preocupa não apenas com o tempo médio necessário para executar sua função, mas com o tempo que leva para uma diversão individual, a idéia de relaxar a pilha em qualquer local arbitrário é muito indesejável.
Um exemplo da vida real para mim: uma biblioteca de matemática. Se sua biblioteca de matemática possui uma Vector
classe que suporta a obtenção de um vetor de unidade na mesma direção, você deve ser capaz de dividir pela magnitude. Se a magnitude for 0, você terá uma situação de divisão por zero. No desenvolvimento, você quer pegar esses . Você realmente não quer uma divisão surpreendente por zeros por aí. Lançar uma exceção é uma solução muito popular para isso. Quase nunca acontece (é um comportamento verdadeiramente excepcional), mas quando acontece, você quer saber.
Na plataforma incorporada, você não deseja essas exceções. Faria mais sentido fazer uma verificaçãoif (this->mag() == 0) return Vector(0, 0, 0);
. Na verdade, eu vejo isso em código real.
Agora pense da perspectiva de um negócio. Você pode tentar ensinar duas maneiras diferentes de usar uma API:
// Development version - exceptions // Embeded version - return 0s
Vector right = forward.cross(up); Vector right = forward.cross(up);
Vector localUp = right.cross(forward); Vector localUp = right.cross(forward);
Vector forwardHat = forward.unit(); Vector forwardHat = forward.tryUnit();
Vector rightHat = right.unit(); Vector rightHat = right.tryUnit();
Vector localUpHat = localUp.unit() Vector localUpHat = localUp.tryUnit();
Isso satisfaz as opiniões da maioria das respostas aqui, mas da perspectiva da empresa isso é indesejável. Os desenvolvedores incorporados terão que aprender um estilo de codificação, e os desenvolvedores de desenvolvimento terão que aprender outro. Isso pode ser bastante desagradável e força as pessoas a uma maneira de pensar. Potencialmente pior: como você prova que a versão incorporada não inclui nenhum código de exceção? A versão lançada pode se misturar facilmente, ocultando-se em algum lugar no seu código até que um caro Comitê de Revisão de Falhas o encontre.
Se, por outro lado, você tiver um sinalizador que ativa ou desativa o tratamento de exceções, os dois grupos podem aprender exatamente o mesmo estilo de codificação. De fato, em muitos casos, você pode até usar o código de um grupo nos projetos do outro grupo. No caso deste código usar unit()
, se você realmente se importa com o que acontece em uma divisão por 0, deve ter escrito o teste você mesmo. Portanto, se você o mover para um sistema incorporado, onde você obtém maus resultados, esse comportamento é "sadio". Agora, da perspectiva dos negócios, treino meus codificadores uma vez e eles usam as mesmas APIs e os mesmos estilos em todas as partes da minha empresa.
Na grande maioria dos casos, você deseja seguir o conselho de outras pessoas: use expressões idiomáticas como tryGetUnit()
ou semelhantes para funções que não geram exceções e, em vez disso, retorne um valor sentinela como nulo. Se você acha que os usuários podem querer usar o código de manipulação de exceções e não exceções lado a lado em um único programa, atenha-se à tryGetUnit()
notação. No entanto, há um caso em que a realidade dos negócios pode melhorar o uso de uma bandeira. Se você se encontrar nessa esquina, não tenha medo de lançar as "regras" pelo caminho. É para isso que servem as regras!