我有一个示例try / catch块。
try
{
...
}
catch (...)
{
...
}
有没有办法从catch(...)块中获取异常对象地址或其他内容?
答案 0 :(得分:2)
如果您至少知道某种类型,那么是的。
catch(...)
语法没有为异常对象指定名称,但可以重新抛出对象并使用更具体的catch
子句:
try {
throw 0;
}
catch(...)
{
try {
throw;
}
catch(int &i)
{
std::cout << &i << std::endl;
}
}
答案 1 :(得分:2)
你可以使用std::current_exception()
在C ++ 11中种类这样做,它返回“指向当前处理的异常的exception_ptr
对象”或副本它。“但是,正如其他答案中所述,由于您不知道实际类型是什么,因此这几乎没有用。请注意,为std::exception_ptr
定义的操作非常少,实际上解除引用它会“导致未定义的行为。”
关于你可以用它做的唯一有趣的事情是保存指针,以便稍后可以使用std::rethrow_exception
在另一个上下文中重新抛出它。这在MSDN article "Transporting Exceptions Between Threads."
答案 2 :(得分:1)
你会如何使用这个地址?
您可以通过
捕获大多数例外情况try {
// something
}
catch (const std::exception& e)
{
// e will be anything derived from std::exception
}
catch(...)
{
// any other error, that you know nothing about
// possibly log it as a problem, and
throw; // pass it on to someone else that might know how to handle it
}
答案 3 :(得分:1)
你不能这样做,因为抛出的对象可以是任何可能的类型,包括普通的旧数据,如int或double。没有办法推断出它的实际类型。
即使语言给你一个指向对象的指针,你仍然无法对它做任何有用的事情,至少不是以类型安全的方式。对于未知数据,它就像 void *。您可以尝试RTTI,但是您也可以捕获您要测试的类型。
对抛出对象的任何有用操作都涉及对其类型做出某种假设,例如公共基类(例如std::exception
或myapp::object
),它允许实际捕获该类型,通用catch(...)
没有必要。
通常,捕获异常时最不想要的是打印消息。这就是为什么从 std :: exception 派生异常是一个好主意,它通过 what()函数提供该消息。这消除了对 catch(...)的需求。