7
votes

Pourquoi lancer une classe sur un énumé?

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;
}


4 commentaires

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.


6 Réponses :


3
votes

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 étant lancé, comment pouvez-vous dire quel type d'erreur le faisait?


2 commentaires

Le type Enum contient des informations sur le type d'erreur. Chaque type Enum est distinct et différent de int 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.



10
votes

Laquelle des deux blocks est plus facile à comprendre: xxx

Le nom d'une classe d'exception devrait vous dire quelque chose sur pourquoi l'exception a été lancée; int ne vous dit rien, vous savez simplement que vous avez attrapé un int , quel que soit ce que cela signifie.


Pour examiner votre exemple mis à jour d'utiliser une énumération au lieu d'un entier, lequel des éléments suivants est plus clair: xxx

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 sauf exception à l'énumération myException , vous auriez inconsciemment Je l'ai attrapé.


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.

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).


4 commentaires

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 , 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.



0
votes

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é.

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.


0 commentaires

0
votes

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.


0 commentaires


5
votes

donné xxx pré>

écrire une clause de capture qui attrape seulement sauf_c code> exceptions. p>

avec p>

struct my_except {};
struct my_except_a : my_except {};
struct my_except_b : my_except {};
struct my_except_c : my_except {};


6 commentaires

attrape (const myException & e) {commutateur (e) {cas sauf_c: pause; Par défaut: lancer; }} 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 .


Et vous pouvez ajouter des chaînes à imprimer la raison pour laquelle il a été lancé.