[英]Catching c++ base exceptions
在我的项目中,我们有一个基本例外。 为了处理显示错误对话框,日志等。 我正在寻找一种处理该异常的所有派生类的方法,我认为这会起作用:
try
{
main_loop();
}
catch (const MyExceptionBase* e)
{
handle_error(e);
}
由于抛出的每个子实例都可以通过指向其父实例的指针来表示。 但是不,现在抛出异常时,它是未处理的异常。
为什么是这样? c ++仅将异常作为引用抛出吗? 从而使我的捕获块无用? 但是,为什么还要首先编译呢?
我能想到的唯一其他方法是:
try
{
main_loop();
}
catch (const ExceptionA& e)
{
handle_error(e);
}
catch (const ExceptionB& e)
{
handle_error(e);
}
catch (const ExceptionC& e)
{
handle_error(e);
}
这似乎有点丑陋。 正确的方法是什么? 没有基础异常类? 还是可以按照我想要的方式解决?
handle_error()
: handle_error()
作用仅仅是使用基类函数display_message_box()
并完全关闭程序。
只需混合两种方法:使用基类,并使用引用。
try
{
main_loop();
}
catch (const MyExceptionBase& e)
{
handle_error(e);
}
BTW C ++可以捕获指针(如果将其抛出)。 但是不建议这样做。
最好的选择是抓住基本参考。 但是请通过引用而不是通过指针进行操作。 例
try
{
main_loop();
}
catch (const MyExceptionBase& e)
{
handle_error(e);
}
通过指针捕获异常的问题是必须由指针抛出异常。 这意味着将使用new创建它。
throw new ExceptionA();
这留下了一个相当大的问题,因为必须在某个时候将其删除,否则就会发生内存泄漏。 谁负责删除此异常? 通常很难做到这一点,这就是为什么大多数人都通过引用来了解。
一般来说,在C ++中,您应该...
按参考捕捉,按价值抛出
如果要抛出指针,则只能使用catch( const sometype* ptr )
,这在99%的情况下是不建议的。
catch( const sometype& ptr )
之所以起作用,是因为r值可以隐式转换为常量引用。
这应该工作:
try {
main_loop();
} catch (const MyExceptionBase &e) {
handle_error(e);
}
我假设ExceptionA / B / C都继承自MyExceptionBase ...我认为应该可以正常工作。
PS:您可能还想考虑从std :: exception继承MyExceptionBase。
令您惊讶的是您原来的示例不起作用。 确实可以使用以下功能(至少在g ++中有效):
class Base { public: virtual ~Base () {} };
class Derived : public Base {};
int main ()
{
try
{
throw new Derived ();
}
catch (Base const * b)
{
delete b;
}
}
我也很确定这可以按照15.3 / 3下的项目符号工作:
处理程序的类型为cv1 T * cv2,E是指针类型,可以通过以下任意一个或全部将其转换为处理程序的类型
您是否要通过公共继承从基本异常类型继承? 基类必须是可访问的基类,这将阻止您的异常被捕获。
根据这里所有其他答案,按引用抛出/捕获有一个优点,就是您不必担心内存的所有权等。但是,如果上面的示例不起作用-那么我不知道为什么引用例子会工作。
正如其他人提到的那样,您应该捕获对基类异常的引用。
至于为什么要首先编译,与Java不同,对于可以引发或捕获哪些类型没有任何限制。 因此,即使从未抛出过任何类型,您都可以放入catch块,并且编译器会很乐意对其进行编译。 由于可以通过指针进行抛出,因此还可以通过指针进行捕获。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.