在C++中,我试图在一次捕获中捕获所有类型的异常(就像C#中的catch(Exception))。这是如何做到的?还有,如何捕获被零除的异常?
catch(Exception)
omjgkv6w1#
当然,你可以使用catch (...) { /* code here */ },但这取决于你想做什么。在C++中,你有确定性析构函数(没有终结化的垃圾),所以如果你想清理,正确的做法是使用RAII。例如。而不是:
catch (...) { /* code here */ }
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,请使用析构函数创建自己的类。
u4dcyp6a2#
您可以使用catch(...)捕获所有内容,但是您无法获得对象来检查、重新抛出、记录,或者用做任何事情。所以...你可以把try块“加倍”,然后重新抛出到一个处理单个类型的外部catch中。如果你为一个自定义异常类型定义了构造函数,这个构造函数可以从你想组合在一起的所有类型中构建自己,那么这是非常理想的。然后,您可以抛出一个从catch(...)构造的默认值,其中可能包含消息或代码,如“UNKNOWN”,或者您希望跟踪此类内容的任何方式。示例:
catch(...)
try { try { // do something that can produce various exception types } catch( const CustomExceptionA &e ){ throw e; } \ catch( const CustomExceptionB &e ){ throw CustomExceptionA( e ); } \ catch( const std::exception &e ) { throw CustomExceptionA( e ); } \ catch( ... ) { throw CustomExceptionA(); } \ } catch( const CustomExceptionA &e ) { // Handle any exception as CustomExceptionA }
qij5mzcb3#
如果我没记错的话(我已经有一段时间没看过C++了),我认为下面的代码应该可以解决这个问题
try { // some code } catch(...) { // catch anything }
而一个快速的谷歌(http://www.oreillynet.com/pub/a/network/2003/05/05/cpluspocketref.html)似乎证明了我是正确的。
0g0grzrc4#
catch (...) { // Handle exceptions not covered. }
重要考虑因素:
ldxq2e6h5#
你不想使用catch (...)(即用省略号捕获),除非你真的、肯定的、最可证明的需要它。这是因为有些编译器(最常见的是Visual C++ 6)也会将诸如分段错误等错误和其他非常糟糕的情况转化为异常,您可以使用catch (...)轻松处理这些异常。这非常糟糕,因为您再也看不到崩溃了。从技术上讲,是的,你也可以捕捉除以零(你必须“StackOverflow”),但你真的应该避免在第一时间进行这样的除法。相反,请执行以下操作:
catch (...)
std::exception
dauxcl2d6#
如果你在windows上,需要处理像被零除和访问冲突这样的错误,你可以使用一个结构化异常转换器,然后在你的转换器中抛出一个c++异常:
void myTranslator(unsigned code, EXCEPTION_POINTERS*) { throw std::exception(<appropriate string here>); } _set_se_translator(myTranslator);
注意,代码会告诉你错误是什么。另外,你需要使用/EHa选项(C/C++ -〉代码生成器-〉启用C/C++异常= Yes with SEH Exceptions)进行编译。如果没有意义,请 checkout [_set_se_translator](http://msdn.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx)))的文档
7kqas0il7#
如果捕获所有异常(包括操作系统异常)确实是您所需要的,那么您需要查看一下您的编译器和操作系统。例如,在Windows上,您可能使用“__try”关键字或编译器开关来使“try/catch”捕获SEH异常,或者两者兼而有之。
ljsrvy3e8#
让你所有的自定义异常类都继承自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!"; } };
fnx2tebb9#
在C++中,标准没有定义被零除的异常,并且实现往往不会抛出它们。
9条答案
按热度按时间omjgkv6w1#
当然,你可以使用
catch (...) { /* code here */ }
,但这取决于你想做什么。在C++中,你有确定性析构函数(没有终结化的垃圾),所以如果你想清理,正确的做法是使用RAII。例如。而不是:
执行以下操作:
如果不使用boost,请使用析构函数创建自己的类。
u4dcyp6a2#
您可以使用
catch(...)
捕获所有内容,但是您无法获得对象来检查、重新抛出、记录,或者用做任何事情。所以...你可以把try块“加倍”,然后重新抛出到一个处理单个类型的外部catch中。如果你为一个自定义异常类型定义了构造函数,这个构造函数可以从你想组合在一起的所有类型中构建自己,那么这是非常理想的。然后,您可以抛出一个从catch(...)
构造的默认值,其中可能包含消息或代码,如“UNKNOWN”,或者您希望跟踪此类内容的任何方式。示例:
qij5mzcb3#
如果我没记错的话(我已经有一段时间没看过C++了),我认为下面的代码应该可以解决这个问题
而一个快速的谷歌(http://www.oreillynet.com/pub/a/network/2003/05/05/cpluspocketref.html)似乎证明了我是正确的。
0g0grzrc4#
重要考虑因素:
catch(...)
还将捕获某些严重的系统级异常(因编译器而异),您将无法可靠地从中恢复。以这种方式捕获这些异常,然后将其吞入并继续可能会导致程序中出现更严重的问题。catch(...)
是可以接受的,前提是异常被重新引发。在这种情况下,您记录所有有用的本地状态信息,然后重新引发异常以允许它向上传播。但是,如果您选择此路由,则应仔细阅读RAII pattern。ldxq2e6h5#
你不想使用
catch (...)
(即用省略号捕获),除非你真的、肯定的、最可证明的需要它。这是因为有些编译器(最常见的是Visual C++ 6)也会将诸如分段错误等错误和其他非常糟糕的情况转化为异常,您可以使用
catch (...)
轻松处理这些异常。这非常糟糕,因为您再也看不到崩溃了。从技术上讲,是的,你也可以捕捉除以零(你必须“StackOverflow”),但你真的应该避免在第一时间进行这样的除法。
相反,请执行以下操作:
std::exception
(正如Adam Pierce建议的那样)并捕获它。dauxcl2d6#
如果你在windows上,需要处理像被零除和访问冲突这样的错误,你可以使用一个结构化异常转换器,然后在你的转换器中抛出一个c++异常:
注意,代码会告诉你错误是什么。另外,你需要使用/EHa选项(C/C++ -〉代码生成器-〉启用C/C++异常= Yes with SEH Exceptions)进行编译。
如果没有意义,请 checkout [_set_se_translator](http://msdn.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx)))的文档
7kqas0il7#
如果捕获所有异常(包括操作系统异常)确实是您所需要的,那么您需要查看一下您的编译器和操作系统。例如,在Windows上,您可能使用“__try”关键字或编译器开关来使“try/catch”捕获SEH异常,或者两者兼而有之。
ljsrvy3e8#
让你所有的自定义异常类都继承自std::exception,然后你就可以简单地捕获std::exception了。
fnx2tebb9#
在C++中,标准没有定义被零除的异常,并且实现往往不会抛出它们。