如何在一个catch块中捕获所有类型的异常?
catch (...)
{
// Handle exceptions not covered.
}
重要考虑:
- 更好的方法是捕获特定类型的异常,你实际上可以从相对于所有可能的异常恢复。 (...)还会捕获某些严重的系统级异常(取决于编译器),您无法从中可靠恢复。以这种方式捕捉它们,然后吞食它们并继续进行,可能会在程序中导致更严重的问题。
- 根据您的上下文,使用catch(...)可以接受,但重新抛出异常。在这种情况下,您记录所有有用的本地状态信息,然后重新抛出异常以允许它传播。但是,如果您选择此路线,则应该阅读RAII pattern。
使所有自定义异常类从std :: exception继承,然后您可以简单地捕获std :: exception。下面是一些示例代码:
class WidgetError
: public std::exception
{
public:
WidgetError()
{ }
virtual ~WidgetError() throw()
{ }
virtual const char *what() const throw()
{
return "You got you a widget error!";
}
};
这是很好的做法,以减少catch块采空区(因为what()返回char字符串,而不是wchar_t字符串) – seand 2010-12-03 01:00:17
如果我没有记错(它已经有一段时间,因为我已经看了C++),我认为下面应该做的伎俩
try
{
// some code
}
catch(...)
{
// catch anything
}
和快速谷歌(http://www.oreillynet.com/pub/a/network/2003/05/05/cpluspocketref.html)似乎证明我是正确的。
在Windows中可能不安全,并且可能它会阻止访问违规和其他真正的错误发生 – seand 2010-12-03 03:58:38
在C++中,标准没有定义除数为零的例外,并且实现往往不会抛出它们。
你不要想要使用catch(...)(即捕获省略号),除非你真的,绝对的,最可证明的需要它。
原因是某些编译器(Visual C++ 6最常见的名称)也会将错误(如段错误和其他非常糟糕的情况)转换为可以使用catch(...)很乐意处理的异常。这很糟糕,因为你再也看不到崩溃了。
从技术上讲,是的,你也可以通过零来捕捉分割(你将不得不为“StackOverflow”),但你应该首先避免做出这样的分割。
相反,做到以下几点:
- 如果你真的知道会发生什么样的异常(S)的,赶上这些类型并没有更多的,和
- 如果你需要给自己抛出异常,并需要捕获所有将抛出的异常,并使这些异常来自std :: exception(正如亚当皮尔斯所建议的)并捕获它。
如果捕获所有异常(包括操作系统异常)实际上是您需要的,那么您需要查看一下编译器和操作系统。例如,在Windows上,您可能会使用“__try”关键字或编译器切换来使“try/catch”捕获SEH异常,或者两者都有。
ebel gil:谢谢你,你的回答非常有帮助! – gil 2008-09-11 09:43:35
当然,您可以使用catch (...) { /* code here */ }
,但它确实取决于您想要做什么。在C++中,你有确定性的析构函数(没有任何最终化垃圾),所以如果你想要扫描,正确的做法是使用RAII。
例如。而不是:
void myfunc()
{
void* h = get_handle_that_must_be_released();
try { random_func(h); }
catch (...) { release_object(h); throw; }
release_object(h);
}
做这样的事情:
#include<boost/shared_ptr.hpp>
void my_func()
{
boost::shared_ptr<void> h(get_handle_that_must_be_released(), release_object);
random_func(h.get());
}
与析构函数创建自己的类,如果你不使用升压。
如果您在Windows上并且需要处理除以零和访问冲突等错误,则可以使用结构化的异常转换程序。然后您翻译的里面,你可以抛出一个C++异常:
void myTranslator(unsigned code, EXCEPTION_POINTERS*)
{
throw std::exception(<appropriate string here>);
}
_set_se_translator(myTranslator);
注意,该代码会告诉你是什么错误。你也需要使用/ EHa选项进行编译(C/C++ - >代码生成 - >启用C/C++异常=有SEH异常)。
如果这样做没有意义结账的文档为[_set_se_translator(http://msdn.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx)
不能让它赶上MySQL的错误(重复键)... – 2012-09-26 19:16:07