[英]How to throw an exception by its run-time type?
我想調用一個可能拋出異常的函數。 如果它確實拋出異常,我想捕獲它並將異常對象傳遞給處理函數。 處理函數的默認實現只是拋出異常。 以下是用於說明問題的削減代碼:
struct base_exception : exception {
char const* what() const throw() { return "base_exception"; }
};
struct derived_exception : base_exception {
char const* what() const throw() { return "derived_exception"; }
};
void exception_handler( base_exception const &e ) {
throw e; // always throws a base_exception object even if e is a derived_exception
}
int main() {
try {
throw derived_exception();
}
catch ( base_exception const &e ) {
try {
cout << e.what() << endl; // prints "derived_exception" as expected
exception_handler( e );
}
catch ( base_exception const &e ) {
cout << e.what() << endl; // prints "base_exception" due to object slicing
}
}
}
但是, exception_handler()
的throw e
exception_handler()
的靜態類型的副本,即base_exception
。 如何使exception_handler()
拋出具有正確運行時類型的derived_exception
的實際異常? 或者我如何重新設計東西以獲得我想要的東西?
您可以將throw_me
虛函數放在基本異常類中,並讓每個派生類覆蓋它。 派生類可以拋出適當的派生類型,而不進行切片。 即使函數在每個類中具有相同的定義,它們也不相同 - *this
的類型在每種情況下都不同。
struct base_exception : exception
{
char const* what() const throw() { return "base_exception"; }
virtual void throw_me() const { throw *this; }
};
struct derived_exception : base_exception
{
char const* what() const throw() { return "derived_exception"; }
virtual void throw_me() const { throw *this; }
};
void exception_handler( base_exception const &e ) {
e.throw_me();
}
你可以使用throw;
重新拋出被捕獲的異常。 您也可以使用模板。
template<typename T> void rethrow(const T& t) { throw t; }
按價值投擲,以參考方式捕獲 。 它會為你省去很多麻煩。
您正在尋找的是被稱為“傳播”異常。 為此,您必須在catch
塊中使用不帶參數的throw
關鍵字。 它不會復制異常,異常將被下一個catch
塊捕獲,或者如果沒有再次捕獲,將使程序中止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.