Ihr Code enthält viele Missverständnisse. Die kurze Antwort ist ja, Sie können what()
ändern, um zurückzukehren, was auch immer Sie wollen. Aber lass uns Schritt für Schritt gehen.
#include <iostream>
#include <exception>
#include <stdexcept>
#include <sstream>
using namespace std;
class DivideByZeroException: public runtime_error {
public:
DivideByZeroException(int x, int y)
: runtime_error("division by zero"), numerator(x), denominator(y)
{}
virtual const char* what() const throw()
{
cnvt.str("");
cnvt << runtime_error::what() << ": " << getNumerator()
<< "/" << getDenominator();
return cnvt.str().c_str();
}
int getNumerator() const
{ return numerator; }
int getDenominator() const
{ return denominator; }
template<typename T>
static T divide(const T& n1, const T& n2)
{
if (n2 == T(0)) {
throw DivideByZeroException(n1, n2);
}
return (n1/n2);
}
private:
int numerator;
int denominator;
static ostringstream cnvt;
};
ostringstream DivideByZeroException::cnvt;
In erster Linie runtime_error
von exception
abgeleitet, ist die beratung Ausnahmeklasse von abzuleiten. Dies wird im stdexcept-Header deklariert. Sie müssen den Konstruktor nur mit der Nachricht initialisieren, die Sie in der Methode what()
zurückgeben möchten.
Zweitens sollten Sie Ihre Klassen entsprechend benennen. Ich verstehe, dass dies nur ein Test ist, aber ein aussagekräftiger Name wird Ihnen immer helfen, Ihren Code zu lesen und zu verstehen.
Wie Sie sehen können, habe ich den Konstruktor geändert, um die Zahlen zu akzeptieren, die die Ausnahme provoziert haben. Du hast den Test in der Ausnahme gemacht ... nun, ich habe das respektiert, aber als eine statische Funktion, die von außen aufgerufen werden kann.
Und schließlich die what()
Methode. Da wir zwei Zahlen teilen, wäre es schön, zwei Zahlen zu zeigen, die die Ausnahme ausgelöst haben. Der einzige Weg, dies zu erreichen, ist die Verwendung von ostringstream. Hier machen wir es statisch, so dass es kein Problem gibt, einen Zeiger auf ein Stapelobjekt zurückzugeben (d. H. cnvt
eine lokale Variable würde ein undefiniertes Verhalten einführen).
Der Rest des Programms ist es mehr oder weniger, wie Sie es in Ihrer Frage aufgeführt:
int main()
{
int a, b, result;
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
{
result = DivideByZeroException::divide(a, b);
cout << "\nThe two numbers divided are " << result << endl;
}
catch(const DivideByZeroException &e)
{
cout << e.what() << endl;
}
return 0;
}
Wie Sie sehen können, habe ich Ihre return main()
Anweisung entfernt haben. Es macht keinen Sinn, da Sie main()
nicht rekursiv aufrufen können. Das Ziel ist auch ein Fehler: Sie würden erwarten, den Vorgang, der die Ausnahme ausgelöst hat, erneut zu versuchen, aber dies ist nicht möglich, da Ausnahmen nicht wiedereintrittsfähig sind.Sie können jedoch ändern, den Quellcode ein wenig, um den gleichen Effekt zu erreichen:
int main()
{
int a, b, result;
bool error;
do {
error = false;
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
{
result = DivideByZeroException::divide(a, b); // trys my exception from my class to see if there is an issue
cout << "\nThe two numbers divided are " << result << endl;
}
catch(const DivideByZeroException &e) // if the error is true, then this calls up the eror message and restarts the progrm from the start.
{
cout << e.what() << endl;
error = true;
}
} while(error);
return 0;
}
Wie Sie sehen können, im Falle eines Fehlers die Ausführung folgt, bis eine „richtige“ Teilung eingegeben wird.
Hoffe, das hilft.
Für einen Start erstellen, ruft 'main' ist rekursiv nicht legal. – jogojapan
'noZero' muss (oder sollte nicht) ein Member innerhalb' testException' sein. Verschiebe es nach draußen! – SuperSaiyan
Die Idee ist normalerweise, dass Sie eine separate Klasse für jeden Ausnahmetyp implementieren. Jeder von ihnen überschreibt die 'what()' -Funktion auf eine andere Art und es steht Ihnen natürlich frei, typbezogene Informationen in die zurückgegebene Zeichenfolge aufzunehmen. – jogojapan