簡體   English   中英

如何通過其運行時類型拋出異常?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM