繁体   English   中英

捕获C ++基本异常

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM