2017-01-12 55 views
6

我剛剛創建了一個異常層次結構,並希望我的catch-block顯示派生異常的消息。 我有5個例外像這樣的:在C++中繼承異常

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


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

他們都是從TGAException衍生,是從的std ::例外的。

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!"; 
} 

所以我當然希望在我的代碼某個時候把這些,並認爲這可能是一個好主意,以減少捕撈塊的,我需要的量。

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

如果我做這樣的消息,將要打印的,是一個從TGAException,但我想讓它顯示了更具體的派生消息。 那麼我需要做些什麼才能按照我想要的方式工作?

+4

抓住引用,如'catch(TGAException&e)'。當你通過價值追趕,你[更切合實際](https://en.wikipedia.org/wiki/Object_slicing) –

+1

更好,因爲你沒有打算改變異常對象,所以趕上const引用。 @IgorTandetnik你應該做出這個答案(或者我會,但我不想偷代表) –

+1

你正在做*對象切片*,直到你通過引用趕上。 –

回答

9

當你趕上這樣的:

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

編譯器,使原始異常的副本,並將其分配到E。它使用TGAException複製構造函數,因此在catch塊內部看到的異常不是ImagetypeException,而是TGAException。這種現象被稱爲對象分割。

如果趕上這樣說:

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

無需拷貝,它會工作,你期望它的方式。

作爲一般指導方針:始終通過引用來捕獲異常,並且幾乎總是通過const引用來捕獲異常。

+0

謝謝!非常有幫助和快速回答:) 但首先noob問題-_-' – Awesome36

+1

不。一個很好的問題。你會驚訝於有多少經驗豐富的C++程序員因爲對象切片而被絆倒(注意:當參數和返回值按值傳遞時,可能發生在方法調用上,或者當目標不是指針或引用時發生)。 –