在C ++中,我试图在一个catch中捕获所有类型的异常(比如C#中的catch(Exception)
)。怎么做?更重要的是,如何才能抓住被零除的例外?
答案 0 :(得分:23)
catch (...)
{
// Handle exceptions not covered.
}
重要注意事项:
答案 1 :(得分:14)
你不想要使用catch(...)(即使用省略号),除非你真的,绝对是最可证明的,需要它。
这样做的原因是一些编译器(Visual C ++ 6命名最常见)也会将分段错误和其他非常糟糕的条件等错误转换为您可以使用catch(...)高兴地处理的异常。这非常糟糕,因为你再也看不到崩溃了。
从技术上讲,是的,你也可以将零除(你必须为“StackOverflow”),但你真的应该避免首先进行这样的划分。
相反,请执行以下操作:
答案 2 :(得分:5)
如果您在Windows上并且需要处理除以零和访问冲突等错误,则可以使用结构化异常转换器。然后在你的翻译器内你可以抛出一个c ++异常:
void myTranslator(unsigned code, EXCEPTION_POINTERS*)
{
throw std::exception(<appropriate string here>);
}
_set_se_translator(myTranslator);
注意,代码会告诉您错误是什么。您还需要使用/ EHa选项进行编译(C / C ++ - &gt; Code Generatrion - &gt;启用C / C ++例外=是SEH例外)。
如果没有意义,请查看[_set_se_translator]的文档(http://msdn.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx)
答案 3 :(得分:4)
如果捕获所有异常 - 包括操作系统异常 - 真的是你需要的,你需要看看你的编译器和操作系统。例如,在Windows上,您可能使用“__try”关键字或编译器开关来“尝试/捕获”捕获SEH异常,或两者兼而有之。
答案 4 :(得分:3)
使所有自定义异常类继承自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!";
}
};
答案 5 :(得分:1)
在C ++中,标准没有定义除零异常,并且实现往往不会抛出它们。
答案 6 :(得分:1)
当然,您可以使用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());
}
如果不使用boost,请使用析构函数创建自己的类。
答案 7 :(得分:0)
如果我没记错的话(自从我看过C ++已经有一段时间了),我认为以下应该可以做到这一点
try
{
// some code
}
catch(...)
{
// catch anything
}
快速谷歌(http://www.oreillynet.com/pub/a/network/2003/05/05/cpluspocketref.html)似乎证明我是正确的。
答案 8 :(得分:0)
您可以使用catch(...)
捕获所有内容,但随后您没有得到一个对象,即可对其进行完全检查,重新抛出,记录或执行任何操作。因此,您可以将try块“加倍”,然后重新放入一个可以处理单个类型的外部捕获器中。如果您为自定义异常类型定义构造函数,该异常类型可以从您希望组合在一起的所有种类中构建自身,则此方法非常理想。然后,您可以从catch(...)
抛出一个默认构造的,其中可能包含诸如UNKNOWN之类的消息或代码,或者您想跟踪这些东西。
示例:
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
}