C++-manual
Förutgående | Kapitel 20. Exceptions | Nästa

# Hierarkier med exceptions

Många västrukturerade system definierar en egen klass för exceptions. Det är som tidigare nämnt helt tillåtet att kasta en klass som en exception. Vi skall definiera en enkel excaption-klass:

    #include <string>

    // exception-klass
    class Exception {
    public:
      Exception (string Text = "Exception") : m_Text (Text) { }
      string m_Text;
    };

Vi har här en enkel exception som innehåller en sträng som fungerar som ett meddelande. Detta meddelanda kan t.ex. skrivas ut på skärmen eller skrivas till en loggfil. Texten som ges har det fördefinierade värdet `"Exception"`. Ganska meningslöst, men fyller sin funktion. Notera att vi automatiskt initialiserar `m_Text` med den givna texten (se avsnittet Initialisering av medlemmar i Kapitel 14). Vi kan nu använda denna klass precis som vilken exception som helst.

## Ärvda exceptions

Att ha en enkel klass för att representera en exception är kanske inte så väldigt praktiskt. Vi kan förstås skicka med en sträng som berättar vad som hänt, mend et är svårt för ett `catch`-block att veta vad som gått fel. Det vore bra att kunna ha mera specificerade exceptions för att göra det lättare att skapa vettiga `catch`-block. Ingenting hidrar oss då ifrån att ärva subklasser av vår `Exception`-klass:

    #include <iostream>
    #include <string>

    // exception-klass
    class Exception {
    public:
      Exception (string Text = "Exception") : m_Text (Text) { }
      string m_Text;
    };

    // subklasser
    class FileNotFound : public Exception {
    public:
      FileNotFound (string Text = "File not found") : Exception (Text) { }
    };

    class PermissionDenied : public Exception {
    public:
      PermissionDenied (string Text = "Permission denied") : Exception (Text) { }
    };

    class InvalidData : public Exception {
    public:
      InvalidData (string Text = "Invalid data") : Exception (Text) { }
    };

    // funktion som genererar en exception
    void test () {
      throw FileNotFound ( string("ingen sådan fil"));
    }

    int main () {
      // försök köra 'test'
      try {
        test ();
      }
      catch ( PermissionDenied E ){
        cout << "Kunde inte öppna filen: " << E.m_Text << endl;
      }
      catch ( FileNotFound E ){
        cout << "Hittade inte filen: " << E.m_Text << endl;
      }
      catch ( InvalidData E ){
        cout << "Felaktig data: " << E.m_Text << endl;
      }
      catch ( Exception E ){
        cout << "Exception: " << E.m_Text << endl;
      }
      catch ( ... ){
        cout << "Annan exception" << endl;
      }
    }

Exemplet använder sig av tre subklasser till `Exception`. De alla kan ha ett unikt meddelande, och det är enkelt för `main()` att kontrollera vilken typ av exception det är frågan om. Notera att en exception i `catch`-block prövas uppifrån och ned, så det första `catch`-block som passar kommer att användas, de övriga ignoreras. Så om vi t.ex. placerar det block som fångar `Exception E` först av alla kommer det att passa även alla subklasser av `Exception`, och därmed inte använda de specialiserade blocken längre ned. Som tumregel kan sägas att man bör placera de mest subklassade eller mest specialiserade blocken först, och gå mot basklasser längre ner. Har man `...` med bör den vara sist.

Förutgående | Hem | Nästa
Ofångade exceptions | Upp | Överlagring av operatorer