[英]C++ - finding the type of a caught default exception
說我有:
try
{
externalLibrary::doSomething();
}
catch (std::exception &e)
{
//yay I know what to do
}
catch (...)
{
//darn, I've no idea what happened!
}
在某些沒有調試信息的外部庫中,可能會出現異常並且您不知道它來自何處或原因的情況。 有沒有辦法找到拋出的內容,或以其他方式獲取與之相關的任何數據? 他們可能會這樣做:
throw myStupidCustomString("here is some really useful information");
但我永遠都不會知道我是否抓住...
如果重要的話,在MSVC ++ 2008中工作。
如果您使用gcc或CLANG,您可以使用技巧來了解“未知”異常類型。 請記住,這是非標准的!
#include <cstdlib>
#include <iostream>
#include <cxxabi.h>
using namespace __cxxabiv1;
std::string util_demangle(std::string to_demangle)
{
int status = 0;
char * buff = __cxxabiv1::__cxa_demangle(to_demangle.c_str(), NULL, NULL, &status);
std::string demangled = buff;
std::free(buff);
return demangled;
}
struct MyCustomClass
{};
int main(int argc, char * argv[])
{
try
{
throw MyCustomClass();
}
catch(...)
{
std::cout << "\nUnknown exception type: '" << util_demangle(__cxa_current_exception_type()->name()) << "'" << std::endl;
}
return(0);
}
因為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.
}
}
用途 :
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;
}
}
}
處理鏈 :
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。
沒有辦法知道C ++中的異常類型(在catch(...)
塊中,我的意思是,cource)
你可以希望你知道究竟是什么externalLibrary::doSomething();
是的,如果你已經寫過,或者,就像你的情況一樣,你可以希望,對於externalLibrary::doSomething();
有非常好的文檔externalLibrary::doSomething();
並閱讀它,如果有的話。 所有好的庫都有詳細的文檔。
你不能在標准的C ++中。 我會認為這些異常非常特殊,並通過嘗試記錄您有一個錯誤異常的事實來處理它們,然后嘗試退出程序,而您仍然可以。
如果幸運的話,您可以保存任何數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.