因为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