C++-Programmierung/ Ausnahmebehandlung/ Übersicht

Aus Wikibooks
Zur Navigation springen Zur Suche springen

Sie haben die Möglichkeit aus Ihren Methoden und Funktionen Rückgabewerte an den Aufrufer weiterzugeben. Sie können Rückgabewerte von Funktionen untersuchen und darauf reagieren.

Rückgabewerte ignorieren[Bearbeiten]

Wir verwenden in einem Programm eine Funktion aus einer Programmierbibliothek einer Datenbank, die eine Datenbankverbindung herstellt db_login sowie eine weitere Funktion daraus, die eine Abfrage ausführt db_exec_query. Diese Funktion gibt zurück, ob die Ausführung funktioniert hat. Es ist aber vorerst unerheblich: Rückgabewerte müssen nicht ausgewertet werden. Verwendet werden diese Funktionen in Ihrer selbsterstellten Funktion abfrage.

Nuvola-inspired-terminal.svg
1 unsigned int nAbfragenzaehler(0);
2 void abfrage (const char * psz_Query)
3 {
4   ++nAbfragenzaehler;
5   db_exec_query(psz_Query);
6 }

Da Sie in Ihrem vorigen Programmablauf bereits vorher db_login ausgeführt haben, gehen Sie davon aus, dass die Verwendung von abfrage immer funktionieren wird. Aber was ist, wenn Sie abfrage nun an einer anderen Stelle verwenden? Was passiert wenn db_exec_query fehlschlägt?

Rückgabewerte auswerten[Bearbeiten]

Da auch eine Dokumentation der Datenbanksoftware vorliegt, erhalten Sie folgende Erkenntnisse:

  • db_exec_query ist folgendermassen deklariert: int db_exec_query(const char * strQ1)
  • Außerdem gibt die Funktion folgende Rückgabewerte:
    • 0 - erfolgreich
    • 1 - kein Login durchgeführt
    • 2 - nicht genügend Speicherplatz

Mit diesen Erkenntnissen können Sie nun ans Werk gehen und abfrage ein bisschen mehr Intelligenz und Wiederverwendbarkeit einhauchen:

Nuvola-inspired-terminal.svg
 1 unsigned int nAbfragenzaehler(0);
 2 void abfrage (const char * psz_Query)
 3 {
 4   int nRetQuery =   // Rückgabewert
 5   db_exec_query(psz_Query);
 6 __Fehler_Untersuchung_Start:  // Sprungmarke für Neuuntersuchung
 7   switch (nRetQuery)
 8   {
 9    case 0: // erfolgreich
10      ++nAbfragenzaehler;
11      break;
12    case 1: // kein Login durchgeführt
13      db_login(); // Login durchführen
14      nRetQuery = db_exec_query(psz_Query); // Noch ein Versuch
15      if (nRetQuery == 1) // Immernoch Login-Problem
16        std::cerr << "Kein gültiger Login für Datenbankabfrage: " << psz_Query << std::endl;
17      else
18        goto __Fehler_Untersuchung_Start; // Nun kein Loginproblem mehr
19      break;
20    case 2: // nicht genügend Arbeitsspeicher
21      std::cerr << "Nicht genug Speicherplatz im Datenbanksystem bei Abfrage: " << psz_Query << std::endl;
22      break;
23    default: // unbekannter Rückgabewert
24      std::cerr << "Fehlercode '" << nRetQuery << "' bei Datenbankabfrage: " << psz_Query << std::endl;
25      break;
26   }
27 }

Der Umbau von abfrage hat folgende Effekte:

  • Der Rückgabewert von db_exec_query wird in jedem Fall ausgewertet.
  • Bei fehlendem Login wird ein Login ausgeführt und die Abfrage erneut ausgeführt.
  • Bei bestehenden Problemen wird eine Fehlermeldung auf stderror ausgegeben.
  • Bei unbekanntem Rückgabewert wird zumindest dieser Wert ausgegeben. Das kann in einem laufenden System die Fehlersuche deutlich vereinfachen.
  • Wenn Sie abfrage an anderen Stellen in Ihrem Programm einsetzen möchten, können Sie sich darauf verlassen, dass entweder ein Login besteht, durchgeführt wird, oder dass eine Fehlermeldung ausgegeben wird.

Rückgabewerte verwenden[Bearbeiten]

Nach der intensiven Auswertung der Rückgabewerte, ergibt es Sinn auch selber Rückgabewerte zu verwenden. Die Funktion int main() beispielsweise ist eine Funktion, die einen Wert vom Typ int zurückgibt. Rückgabewerte müssen nicht ausgewertet werden. Wenn eine Methode/Funktion mit Rückgabewert deklariert ist, muss aber an jedem Aussprungpunkt auch ein passender Wert zurückgegeben werden.

Im folgenden Beispiel wird eine Funktion definiert, die Eingabeparameter auswertet und davon abhängig verschiedene Werte zurückgibt.

Nuvola-inspired-terminal.svg
 1 // Funktion die einen Wert vom Typ int zurückgibt
 2 int main( int argc, char *argv[], char *envp[]) 
 3 {
 4 	if (argc > 1)
 5 	{
 6 		std::cout << "Mehr als ein Parameter." << std::endl;
 7 		return 1;
 8 	}
 9 	return 0;
10 }

Ein Aufrufer dieser Funktion bekommt nun einen Rückgabewert von '0', wenn der Wert von argc kleiner oder gleich '1' ist. Sonst gibt diese Funktion den Wert '1' zurück.

Merken Sie sich Folgendes:

Rückgabewerte:

  • haben immer einen Typ.
  • müssen nicht ausgewertet werden.
  • müssen an jeder Aussprungstelle angegeben werden, wenn eine Methode/Funktion mit Rückgabetyp deklariert wird.
  • können auch überhaupt nicht verwendet werden, deklarieren Sie dazu void als Rückgabetyp.