我可以获得
捕获的异常的描述catch(...)
阻止?类似std :: exception的 .what()。
答案 0 :(得分:40)
您可以使用一个技巧:
catch(...) {
handle_exception();
}
void handle_exception() {
try {
throw;
} catch (const std::exception &e) {
std::cout << e.what() << "\n";
} catch (const int i) {
std::cout << i << "\n";
} catch (const long l) {
std::cout << l << "\n";
} catch (const char *p) {
std::cout << p << "\n";
} catch (...) {
std::cout << "nope, sorry, I really have no clue what that is\n";
}
等等,因为您可能会抛出许多不同的类型。如果你真的什么都不知道什么可能会抛出,那么即使是倒数第二个也是错误的,因为有人可能会抛出一个char*
而不指向以空字符结尾的字符串。
抛出任何不是std::exception
或派生类的东西通常是个坏主意。 std::exception
存在的原因是允许每个人抛出并捕获他们可以做一些有用的对象。在玩具程序中,你只想离开那里,甚至不能打扰包含一个标准的标题,好吧,可能会抛出一个int
或一个字符串文字。我不认为我会成为正式界面的一部分。您抛出的任何异常都是正式界面的一部分,即使您以某种方式忘记记录它们。
答案 1 :(得分:5)
该块可能捕获int,或const char *,或任何其他内容。当编译器对它一无所知时,编译器怎么可能知道如何描述呢?如果您想从异常中获取信息,您必须知道类型。
答案 2 :(得分:4)
如果您知道只抛出std :: exception或子类,请尝试
catch(std::exception& e) {...e.what()... }
否则,正如DeadMG写的那样,既然你可以扔掉(差不多)所有东西,你就不能假设你抓到了什么。
通常,catch(...)只应在使用写得不好或文档化的外部库时用作最后的防御。所以你会使用层次结构
catch(my::specialException& e) {
// I know what happened and can handle it
... handle special case
}
catch(my::otherSpecialException& e) {
// I know what happened and can handle it
... handle other special case
}
catch(std::exception& e) {
//I can at least do something with it
logger.out(e.what());
}
catch(...) {
// something happened that should not have
logger.out("oops");
}
答案 3 :(得分:3)
从C ++ 11开始,您可以使用指针捕获当前异常:
std::exception_ptr p; // default initialization is to nullptr
try {
throw 7;
}
catch(...)
{
p = std::current_exception();
}
这就像一个智能指针;只要至少有一个指针指向异常对象,它就不会被销毁。
稍后(甚至可能在不同的功能中)您可以采用与当前最佳答案类似的方式采取行动:
try {
if ( p )
std::rethrow_exception(p);
}
catch(int x)
{
}
catch(std::exception &y)
{
}
答案 4 :(得分:2)
我们如何实现我们的异常是,我们有自己的异常类,它们都来自std::exception
..
我们的例外将包含异常消息,函数名称,文件名和行,其中生成异常。这些不仅可用于显示消息,还可用于日志记录,这有助于轻松诊断异常。因此,我们获取有关生成的异常的完整信息。
请记住我们的例外情况,以获取有关错误的信息。所以,在这方面,每一点信息都有帮助。
答案 5 :(得分:2)
引用bobah
#include <iostream>
#include <exception>
#include <typeinfo>
#include <stdexcept>
int main()
{
try {
throw ...; // throw something
}
catch(...)
{
std::exception_ptr p = std::current_exception();
std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
return 1;
}