Je me demandais, pourquoi est-il préférable de jeter une classe sur un énorme
Sûrement jetant des classes est plus aérien? p>
par exemple p>
enum MyException { except_a, except_b, except_c } void function f(){ throw except_a; } int main(int arc, char* argv[]){ try{ } catch (MyException e){ switch(e){ except_a: break; except_b: break; except_c: break; } } return 0; }
6 Réponses :
Une classe peut avoir des choses comme un message d'erreur à l'intérieur, et peut avoir un nom significatif qui indique quel type d'exception qu'il représente. Si vous voyez un int code> étant lancé, comment pouvez-vous dire quel type d'erreur le faisait? P>
Le type Enum code> contient des informations sur le type d'erreur. Chaque type
Enum code> est distinct et différent de
int code> en C ++. J'ai écrit un petit échantillon de code à IDEONE.COM/PMKXV , vérifiez-le.
@Potatoswatter: Dans la défense de @ Jeremiah, le PO a totalement changé la question. Cette réponse a rendu beaucoup plus de sens avant le changement.
Laquelle des deux blocks code> code> est plus facile à comprendre: Le nom d'une classe d'exception devrait vous dire quelque chose sur pourquoi l'exception a été lancée; Pour examiner votre exemple mis à jour d'utiliser une énumération au lieu d'un entier, lequel des éléments suivants est plus clair: p> Il n'y a aucune raison de préférer le premier formulaire: il n'y a pas de prestation de performance et le code est moins clair et plus sujette d'erreur. Dans votre exemple, vous avez oublié de repenser l'exception si vous ne manipulez pas cela, alors si quelqu'un a ajouté plus tard un Quant à votre question "surhead", cela dépend, mais probablement pas. Il devrait être (relativement) rare qu'une exception soit lancée, et si vous avez une boucle serrée où la performance compte vraiment, vous n'utilisez pas d'exceptions de toute façon. P> Le bénéfice de l'utilisation de hiérarchies de classe pour Des exceptions sont qu'ils vous permettent d'écrire un code plus claire, tout comme l'avantage de l'utilisation de flux de contrôle non local (exceptions) au lieu d'autres approches telles que les valeurs de retour d'erreur, vous permet d'écrire un code plus clair (au moins lorsque vous utilisez des exceptions correctement). p> p> int code> ne vous dit rien, vous savez simplement que vous avez attrapé un
int code>, quel que soit ce que cela signifie. p>
sauf code> exception à l'énumération code> myException code>, vous auriez inconsciemment Je l'ai attrapé. p>
Le 1er one me semble facile: p. Vous n'avez pas besoin d'ajouter une prise (exception e)?
Désolé, je voulais dire Enum (voir question).
@ABC: Vous faites si vous souhaitez attraper une exception de type exception code>, oui.
Je ne pense pas que ce soit une grande partie d'un argument. Vous pouvez facilement nommer les Enums en utilisant un peu d'intelligence et obtenir le même affect avec une instruction de commutation. Un meilleur argument serait la hiérarchie de la classe et la capacité de stocker des informations supplémentaires dans un objet.
Il ne s'agit pas de la performance. Le lancement d'exception n'est pas la chose que vous souhaitez accroître régulièrement dans un algorithme intensif de la CPU. Et la surcharge de déroulement de la pile est beaucoup plus que le port de l'objet lancé. P>
Il s'agit de pouvoir regrouper les informations sur le type d'erreur survenu. Il s'agit de préciser l'utilisateur de votre bibliothèque ce que vous lancez comme une erreur et pourquoi. Un entier ou un flotteur ne supporte pas vraiment beaucoup d'informations. P>
Les frais généraux n'a pas d'importance, car les exceptions sont toujours chères. Une instance d'une classe peut contenir plus d'informations et vous pouvez attraper des bases. P>
La surcharge dans l'envoi de l'exception est susceptible d'être bien plus que de copier une classe simple. J'ai mesuré que c'est des milliers de cycles dans Cette question a >. Donc, la performance est essentiellement discutée. P>
En outre, une valeur La plus facile et la meilleure chose à faire est de commencer avec Enum code> car l'élément unique d'une classe est tout aussi rapide de copier comme une valeur
Enum code> sans cours autour de lui. Des exceptions peuvent être comme des gratters pour des notes aléatoires pour sortir d'une confiture. Il est tout simplement trop probable que vous souhaitiez plus de données, qui seront au début (gasp) doubler la surcharge sur celle de deux
int code> S 'vaut. P>
std: exception code>, et que les classes ne soient jamais dérivées de celle-ci. P>
donné écrire une clause de capture qui attrape seulement avec p> sauf_c code> exceptions. p>
struct my_except {};
struct my_except_a : my_except {};
struct my_except_b : my_except {};
struct my_except_c : my_except {};
attrape (const myException & e) {commutateur (e) {cas sauf_c: pause; Par défaut: lancer; }} code> c'est beaucoup de travail!
@James: De plus, ça n'a pas échoué.
Je pense que cela la meilleure réponse. Merci. avoir à repasser par défaut est un peu douloureux.
@Jamesmcnellis: Si (E! = Sauf_c) lancer;
@Fred: Modifions donc l'obligation d'attraper A et C uniquement. Avec des classes, vous pouvez exploiter le héritage et attraper une classe de base commune. Avec Enums, vous êtes de retour chez James ' Switch CODE>.
Et vous pouvez ajouter des chaînes à imprimer la raison pour laquelle il a été lancé.
Vous ne jetez pas une classe; Vous lancez un objet, qui peut être un objet de type de classe.
Désolé, je voulais dire énumé non int.
Hey tu as radicalement changé la question
Je voulais dire que tout le long et je viens d'ajouter un exemple. La chose est que Enum est traité comme des int's s'ils sont Sans nom.