Comment créer des exceptions?
J'ai donc une prochaine cession portant sur les exceptions et les utiliser dans mon carnet d'adresses actuel programme que la plupart des devoirs est centrée autour de. J'ai décidé de jouer avec les exceptions et l'ensemble de try catch chose, et en utilisant une conception de classe, qui est ce que je vais finir par avoir à faire pour mon affectation dans une couple de semaines. J'ai le travail de code permettant de vérifier l'exception tout simplement beau, mais ce que je veux savoir, c'est si il existe un moyen de normaliser mon message d'erreur de la fonction, (j'.e mon ce() call):
S voici mon code:
#include <iostream>
#include <exception>
using namespace std;
class testException: public exception
{
public:
virtual const char* what() const throw() //my call to the std exception class function (doesn't nessasarily have to be virtual).
{
return "You can't divide by zero! Error code number 0, restarting the calculator..."; //my error message
}
void noZero();
}myex; //<-this is just a lazy way to create an object
int main()
{
void noZero();
int a, b;
cout << endl;
cout << "Enter a number to be divided " << endl;
cout << endl;
cin >> a;
cout << endl;
cout << "You entered " << a << " , Now give me a number to divide by " << endl;
cin >> b;
try
{
myex.noZero(b); //trys my exception from my class to see if there is an issue
}
catch(testException &te) //if the error is true, then this calls up the eror message and restarts the progrm from the start.
{
cout << te.what() << endl;
return main();
}
cout <<endl;
cout << "The two numbers divided are " << (a / b) << endl; //if no errors are found, then the calculation is performed and the program exits.
return 0;
}
void testException::noZero(int &b) //my function that tests what I want to check
{
if(b == 0 ) throw myex; //only need to see if the problem exists, if it does, I throw my exception object, if it doesn't I just move onto the regular code.
}
Ce que je voudrais être capable de faire c'est donc mon ce() la fonction peut renvoyer une valeur dépend de quel type d'erreur est appelé. Ainsi, par exemple, si je devais appeler une erreur qui ressemblait le plus grand nombre,(un), pour voir si c'était un zéro, et si elle l'était, elle serait alors le message pour dire que "vous ne pouvez pas avoir un numérateur de zéro", mais encore être à l'intérieur de la ce() fonction. Voici un exemple:
virtual const char* what() const throw()
if(myex == 1)
{
return "You can't have a 0 for the numerator! Error code # 1 "
}
else
return "You can't divide by zero! Error code number 0, restarting the calculator..."; //my error message
}
De toute évidence, cela ne fonctionnerait pas, mais est-il un moyen de le faire donc je ne suis pas écrire une fonction différente pour chaque message d'erreur?
- Pour commencer, appelant
main
de manière récursive n'est pas légal. noZero
nécessité de ne pas (ou ne devraient pas) être un membre à l'intérieur detestException
. Déplacer à l'extérieur!- L'idée est généralement que vous implémentez une classe distincte pour chaque type d'exception. Chacun d'eux remplace la
what()
fonctionnent d'une façon différente, et vous êtes évidemment libre d'inclure liées à un type d'information dans la chaîne de caractères qu'elle renvoie. - Attendez, créer un classe différente pour chaque erreur? N'est-ce pas sembler un peu exagérer? Pourquoi ne serait-il pas mieux de créer une classe d'exception qui couvre les erreurs de votre recherche d', au lieu fo un tas de catégories distinctes?
- Ce que j'essaie de voir, c'est que si vous pouvez mettre en œuvre une sorte de variable, éventuellement, à l'intérieur tout ce que vous jetez, qui peut être lu par la ce et ensuite utilisée pour décider lequel d'erreur de retour
- Non, il n'est pas! Vous disposez d'un module spécifique d'exception générale. Chaque classe d'exception que vous créez, dans ce module, héritent de cette classe d'exception. De cette façon, vous pouvez avoir plusieurs clauses catch, au lieu d'avoir une clause catch et une série de if-else. Aussi vous pouvez avoir le niveau du module exception interceptée, à la fin, si vous ne se soucient quelques exceptions près.
- Un autre en-tête qui ressemble à ceci:
class numZeroExp: public exception { public: virtual const char* what() const throw() { return "You numerator cannot be zero! Error code number 0, restarting the calculator..."; } void numZeroExp::noZero(int &a) { if(a == 0 ) throw myex; } }myex; class denZeroExp: public exception { public: virtual const char* what() const throw() { return "You can't divide by zero! Error code number 0, restarting the calculator"; } void denZeroExp::noZero(int &b) { if(b == 0 ) throw myex2; } }myex2;
- Fondamentalement, j'ai deux classes, à la fois à l'aide de la valeur par défaut exception appel à ce que(), avec les messages distincts. Est-ce exact?
Vous devez vous connecter pour publier un commentaire.
Votre code contient beaucoup d'idées fausses. La réponse courte est oui, vous pouvez changer
what()
afin de retourner tout ce que vous voulez. Mais allons-y étape par étape.En premier lieu,
runtime_error
, dérivé deexception
, est conseillé à l'exception de la classe à dériver. Cela est déclaré dans le stdexcept en-tête. Vous n'avez qu'à initialiser son constructeur avec le message que vous allez revenir dans lewhat()
méthode.Deuxièmement, vous devriez correctement le nom de vos classes. Je comprends que c'est juste un test, mais un nom descriptif sera toujours aider à lire et à comprendre votre code.
Comme vous pouvez le voir, j'ai changé le constructeur afin d'accepter les chiffres de fracture qui a provoqué l'exception. Vous avez fait le test à l'exception... et bien, j'ai respecté cela, mais comme une fonction statique qui peut être invoqué à partir de l'extérieur.
Et enfin, la
what()
méthode. Puisque nous sommes à la division de deux nombres, il serait bien de montrer que les deux nombres qui ont provoqué l'exception. La seule façon d'y parvenir est l'utilisation de ostringstream. Ici nous faire statiques, donc il n'y a pas de problème de retour d'un pointeur vers une pile d'objet (c'est à dire, avoircnvt
une variable locale permettrait d'introduire un comportement indéterminé).Le reste du programme est plus ou moins comme vous l'avez placée dans votre question:
Comme vous pouvez le voir, j'ai supprimé votre
return main()
instruction. Il n'a pas de sens, puisque vous ne pouvez pas appelermain()
de manière récursive. Aussi, l'objectif de cela est une erreur: vous attendez pour recommencer l'opération qui a provoqué l'exception, mais ce n'est pas possible, puisque les exceptions ne sont pas réentrant. Vous pouvez, cependant, modifier le code source un peu, pour obtenir le même effet:Comme vous pouvez le voir, dans le cas d'une erreur à l'exécution suit jusqu'à ce qu'un "bon" de la division est entré.
Espère que cette aide.
std
lève des exceptions de<stdexcept>
.myException(string s) : runtime_error(s) { }
me permet de lancer le constructeur à l'intérieur quelle que soit la fonction que je suis en essais pour une erreur, et il suffit d'entrer le message dans la surcharge. À l'intérieur de mon carnet d'adresse, lorsque l'utilisateur est à la recherche d'un nom enregistré, mais il n'existe pas, je jette ce:throw myException("Person not in Address Book ");
à l'intérieur de mon try catch, et je peux changer le message pour s'adapter à l'erreur à chaque fois! Donc merci à tous pour l'aide, je l'obtenir maintenant!return cnvt.str().c_str();
danswhat()
causer des problèmes? str() renvoie un temp copie, c_str() les points de la mémoire tampon interne dans ce temp, une fois retourné, le temp est détruit et le pointeur retourné (donné par c_str()) est maintenant invalide..?Vous pouvez créer votre propre classe d'exception pour la longueur d'erreur comme ceci
Vous devriez toujours utiliser std::exception&e. donc, ne
catch(std::exception &e)
alors je serais coincé avec la valeur par défaut .quelle sortieVous devriez envisager une hiérarchie de classes.
La raison pour laquelle il pourrait ne pas être évident lorsque vous essayez d'utiliser les exceptions juste pour le transfert d'une chaîne de caractères, mais réelle intention d'utiliser des exceptions si un mécanisme avancé de la manipulation de situations exceptionnelles. Beaucoup de choses sont faites sous le capot de C++ runtime environnement lors de la pile d'appels est déroulée lorsque vous voyagez à partir de 'jeter' correspondait à "attraper".
Un exemple de classes pourrait être:
Dans certains cas, ils doivent être spécifiques
dans d'autres, de ne pas
Que pour quelques détails supplémentaires,
catch (const testException &te)
à moins que vous vraiment besoin d'un non-objet constant.