因爲C++是靜態類型的,所以你必須捕獲一個已知類型。但是,您可以調用一個外部函數(或一組函數)來處理在您調用它們時未知的異常類型。如果這些處理程序都具有已知類型,則可以註冊它們以進行動態嘗試。
struct myStupidCustomString {
myStupidCustomString(char const *what) : what (what) {}
char const *what;
};
void throws() {
throw myStupidCustomString("here is some really useful information");
}
// The external library can provide a function, or you can provide a wrapper, which
// extracts information from "unknown" exception types.
std::string extract_from_unknown_external_exception() {
try { throw; }
catch (myStupidCustomString &e) {
return e.what;
}
catch (...) {
throw; // Rethrow original exception.
}
}
Use:
void example() {
try { throws(); }
catch (...) {
try {
std::string extracted = extract_from_unknown_external_exception();
std::cout << "extracted: " << extracted << '\n';
}
catch (...) {
// Chain handlers for other types; e.g. exception types from other libraries.
// Or do something generic for the unknown exception.
// Or rethrow the original unknown exception:
throw;
}
}
}
Handler chain:
typedef std::string Extract();
std::vector<Extract*> chain (1, &extract_from_unknown_external_exception);
// Chain would normally be initialized using whatever scheme you prefer for
// initializing global objects.
// A list or other container (including a manual linked list that doesn't
// require dynamic allocation) may be more appropriate, depending on how you
// want to register and unregister handlers.
std::string process_chain() {
for (std::vector<Extract*>::iterator x = chain.begin(); x != chain.end(); ++x) {
try {
return (*x)();
}
catch (...) {} // That handler couldn't handle it. Proceed to next.
}
throw; // None could handle it, rethrow original exception.
}
void example() {
try { throws(); }
catch (...) {
try {
std::string extracted = process_chain();
std::cout << "extracted: " << extracted << '\n';
}
catch (...) {
throw; // Rethrow unknown exception, or otherwise handle it.
}
}
}
最後,如果你知道實現細節,你可以使用這些提取任何額外的信息,請執行會公開。 C++ 0x也以便攜的方式公開了一些細節;看看std :: exception_ptr。
根據我的經驗,異常的詳細文檔並不像體面的params文檔那樣普遍。但是,如果是這樣,我只需要測試標準的可能性......系統異常呢? – 2011-02-03 11:35:25
你是什麼意思「系統異常呢?」我不知道他們是否可以在C++程序中被捕獲:?此外,我使用的大多數庫都有自己的異常層次結構,並且有很好的文檔記錄。但是,當然,這並不意味着所有圖書館都有這樣的事情。另外,如果它是C庫,你知道,沒有例外拋出。 – 2011-02-03 11:40:11
我的意思是,沒有特殊的方法來捕捉像null-ptr訪問,div/0之類的東西嗎?我認爲有方法可以在第三方庫存在bug的情況下捕獲這些問題? – 2011-02-03 14:36:43