Frage

In meinem Projekt haben wir eine Basis Ausnahme. zeigt Fehlerdialoge für die Handhabung, melden und so. Im Suche nach einem Weg, alle abgeleiteten Klassen von dieser Ausnahme zu behandeln, dachte ich, das würde funktionieren:

try
{
  main_loop();
}
catch (const MyExceptionBase* e)
{
  handle_error(e);
}

Wie jedes Kind könnte beispielsweise durch einen Zeiger auf seine Eltern vertreten geworfen werden. Aber nein, wenn Ausnahmen sind jetzt geworfen, das eine nicht behandelte Ausnahme.

Warum ist das? Sie C ++ nur Ausnahmen als Referenzen werfen? Dadurch macht meinen catch-Block nutzlos? Aber warum ist diese auch in erster Linie kompilieren?

Die einzige andere Art, wie ich denken kann, ist dies:

try
{
  main_loop();
}
catch (const ExceptionA& e)
{
  handle_error(e);
}
catch (const ExceptionB& e)
{
  handle_error(e);
}
catch (const ExceptionC& e)
{
  handle_error(e);
}

Welche scheint irgendwie hässlich. Was ist der richtige Weg, dies zu tun? Dont haben eine Klasse Basis Ausnahme? Oder kann es in der Art und Weise gelöst werden, ich will?

Ps. Was handle_error() tut, ist einfach die Verwendung der Basisklasse Funktion display_message_box() und sauber Shutdown das Programm machen

War es hilfreich?

Lösung

Nur die beiden Ansätze mischen: die Basisklasse verwenden, und eine Referenz verwenden

.
try
{
  main_loop();
}
catch (const MyExceptionBase& e)
{
  handle_error(e);
}

BTW C ++ können Zeiger fangen, wenn man sie werfen. Es ist allerdings nicht ratsam.

Andere Tipps

Ihre beste Wette ist, um die Basisreferenz zu fangen. Aber tun Sie dies bitte Bezug genommen wird, nicht durch den Zeiger. Beispiel

try
{
  main_loop();
}
catch (const MyExceptionBase& e)
{
  handle_error(e);
}

Das Problem mit einer Ausnahme durch den Zeiger zu kontrollieren ist, dass es durch den Zeiger geworfen werden muss. Das bedeutet, dass es mit neuem geschaffen werden.

throw new ExceptionA();

Dies läßt ein ziemlich großes Problem, weil es zu einem bestimmten Zeitpunkt gelöscht werden muß, oder Sie haben einen Speicherverlust. Wer sollte zum Löschen dieser Ausnahme verantwortlich sein? Es ist generell schwierig, dieses Recht zu bekommen, weshalb die meisten Menschen durch Bezugnahme fangen.

In der Regel in C ++ sollten Sie ...

  

Fang durch Bezugnahme eingeschlossen, throw von Wert

Sie können nur verwenden, wenn Sie catch( const sometype* ptr ) Zeiger werfen, die unter 99% Umständen nicht ratsam ist.

Der Grund catch( const sometype& ptr ) funktioniert, weil r-Werte implizit konvertierbar zu konstanten Referenzen sind.

Dies sollte funktionieren:

try {
  main_loop();
} catch (const MyExceptionBase &e) {
  handle_error(e);
}

Ich gehe davon aus ExceptionA / B / C alle aus MyExceptionBase erbt ... ich denke, das sollte gut funktionieren.

PS: Sie möchten auch MyExceptionBase inhert von std :: exception berücksichtigen zu müssen

.

Ich bin überrascht, dass Ihr ursprüngliches Beispiel funktioniert nicht. Die folgende funktioniert (zumindest mit g ++):

class Base { public: virtual ~Base () {} };
class Derived : public Base {};

int main ()
{
  try
  {
    throw new Derived ();
  }
  catch (Base const * b)
  {
    delete b;
  }
}

Ich bin auch ziemlich sicher, dass dies beabsichtigt ist, als je eine Kugel zu arbeiten unter 15.3 / 3:

  

der Handler ist vom Typ CV1 T * CV2 und E ist ein Zeigertyp, der durch eine oder beide der

auf den Typ des Handlers umgewandelt werden kann

erben Sie von dem Basisausnahmetyp über öffentliche Vererbung? Die Basisklasse muss eine leicht zugängliche Basis sein und dies würde Ihre Ausnahme von gefangen stoppen.

Wie pro allen anderen Antworten hier, werfen / durch Bezugnahme fangen den Vorteil, dass hat Sie müssen nicht über das Eigentum an den Speicher usw. kümmern Aber wenn das obige Beispiel funktioniert nicht - dann weiß ich nicht, warum das Referenzbeispiel funktionieren würde.

Wie andere erwähnt haben, sollten Sie einen Verweis auf die Basisklasse Ausnahme fangen.

Was, warum es kompiliert in erster Linie, im Gegensatz zu Java, gibt es keine Einschränkungen für welche Arten geworfen oder gefangen werden können. So können Sie für jede Art in einem catch-Block setzen, auch wenn es nie geworfen wird, und der Compiler wird es glücklich kompilieren. Da Sie können werfen durch Zeiger, können Sie auch durch den Zeiger fangen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top