2017-01-12 12 views
6

Właśnie utworzyłem hierarchię wyjątków i chcę, aby mój blok catch pokazywał komunikat wyprowadzonego wyjątku. mam 5 wyjątki takie jak ten:Dziedzicz wyjątki w C++

class ImagetypeException : public TGAException { 
public: 
const char* what() const throw(); 
}; 


const char* ImagetypeException::what() const throw() { 
    return "Der Bildtyp ist nicht \"RGB unkomprimiert\"."; 
} 

Wszystkie z nich są pochodzące od TGAException, że pochodzi z std :: wyjątku.

class TGAException : public std::exception { 
public: 
    virtual const char* what() const throw(); 
}; 

const char* TGAException::what() const throw() { 
    return "Beim Einlesen oder Verarbeiten der TGA-Datei ist ein unerwarteter Fehler aufgetreten!"; 
} 

Więc oczywiście chcą rzucić te w pewnym momencie mojego kodu i że może to być dobry pomysł, aby zminimalizować ilość połowów bloków muszę.

catch (TGAException e) { 
     cout << e.what() << endl; 
    } 

Jeśli zrobić to w ten sposób, komunikat, który zostanie wydrukowany, jest jednym z TGAException, ale chcę, aby pokazać bardziej konkretne wiadomości pochodzące. Co więc muszę zrobić, aby to działało tak, jak tego chcę?

+4

Złap według referencji, tak jak w 'catch (TGAException & e)'. Po złapaniu przez wartość, [plaster go] (https://en.wikipedia.org/wiki/Object_slicing) –

+1

jeszcze lepiej, catch przez odniesienie do const, ponieważ nie planujesz zmienić obiektu wyjątku. @IgorTandetnik powinieneś zrobić to odpowiedź (albo ja, ale nie próbuję kraść rep) –

+1

Robisz * Przecinanie obiektów *, dopóki nie złapie przez odniesienie. –

Odpowiedz

9

Kiedy złapiesz tak:

catch (TGAException e) { 
    cout << e.what() << endl; 
} 

Kompilator tworzy kopię oryginalnego wyjątku i przypisuje go do e. Używa konstruktora kopiowania TGAException, więc wyjątek widziany wewnątrz bloku catch nie jest wyjątkiem ImagetypeException, jest to wyjątek TGAException. Zjawisko to nazywa się krojeniem obiektów.

Jeśli złapiesz to w ten sposób:

catch (const TGAException & e) { 
    cout << e.what() << endl; 
} 

Kopia nie jest potrzebna i będzie działać zgodnie z oczekiwaniami go.

Jako ogólna wytyczna: Zawsze chwytaj wyjątki przez odniesienie i prawie zawsze łapaj je przez odniesienie do stałych.

+0

dzięki! bardzo pomocna i szybka odpowiedź :) ale pytanie noob na pierwszym miejscu -_- ' – Awesome36

+1

Nie. Dobre pytanie. Zdziwiłbyś się, ilu doświadczonych programistów C++ wpadło w pułapkę nad przecinaniem obiektów (uwaga: może się zdarzyć w wywołaniach metod, gdy parametry i zwracane wartości są przekazywane przez wartość, lub nawet przypisania, gdy cel nie jest wskaźnikiem lub odniesieniem). –