说我有:
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工作如果重要.
解决方法@H_502_14@
因为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;
}
}
}
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.
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; } } }
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.