如何在一个catch块中捕获所有类型的异常?
在C ++中,我试图一次捕获所有类型的异常(例如C#中的catch(Exception)
)。怎么做?而且,如何捕获零除异常?
解决方案
回答
catch (...) { // Handle exceptions not covered. }
重要注意事项:
- 更好的方法是捕获实际可以从中恢复的特定类型的异常,而不是所有可能的异常。
- catch(...)还将捕获某些严重的系统级异常(因编译器而异),我们将无法从中可靠地恢复这些异常。以这种方式捕获它们,然后将其吞下并继续可能会在程序中引起进一步的严重问题。
- 根据上下文,使用catch(...)是可以接受的,前提是该异常被重新抛出。在这种情况下,我们记录所有有用的本地状态信息,然后重新引发异常以使其向上传播。但是,如果选择此路线,则应阅读RAII模式。
回答
让我们所有的自定义异常类都继承自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!"; } };
回答
如果我没记错(自从看过C ++已经有一段时间了),我认为以下方法可以解决问题
try { // some code } catch(...) { // catch anything }
和一个快速的谷歌(http://www.oreillynet.com/pub/a/network/2003/05/05/cpluspocketref.html)似乎证明我是正确的。
回答
在C ++中,该标准未定义零除异常,并且实现往往不会抛出它们。
回答
我们不希望使用catch(...)(即用省略号进行catch),除非我们确实,确实,大多数可证明的人都需要它。
这样做的原因是某些编译器(最常见的是Visual C ++ 6)也将诸如段错误和其他真正糟糕的条件之类的错误转换为可以使用catch(...)轻松处理的异常。这非常糟糕,因为我们不再看到崩溃了。
从技术上讲,是的,我们还可以用零除(必须使用" StackOverflow"),但实际上我们应该首先避免进行此类除。
而是,请执行以下操作:
- 如果我们实际上知道将要遇到的异常类型,则不要再捕获这些类型,并且
- 如果我们需要自己抛出异常,并且需要捕获将要抛出的所有异常,请使这些异常派生自std :: exception(如Adam Pierce所建议)并捕获该异常。
回答
如果确实需要捕获包括OS异常在内的所有异常,则需要查看编译器和OS。例如,在Windows上,我们可能具有" __try"关键字或者编译器开关,以使" try / catch"捕获SEH异常,或者同时发生这两种情况。
回答
当然,我们可以使用catch(...){/ *代码* /}
,但这实际上取决于我们要执行的操作。在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()); }
如果我们不使用boost,请使用析构函数创建自己的类。
回答
如果我们在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/zh-cn/library/5z4bw5h5(VS.80).aspx)