是否可以同时拥有两个或更多活动异常?

时间:2018-01-04 03:23:51

标签: c++ exception exception-handling standards c++17

C ++ 17引入了一个新函数std::uncaught_exceptions

  

检测已抛出或重新抛出的异常数量   输入了匹配的catch子句。

以下代码:

#include <iostream>

using namespace std;

struct A
{
    ~A()
    {
        cout << std::uncaught_exceptions() << endl;
    }
};

int main()
{
    try
    {
        try
        {

            A a1;
            throw 1;
        }
        catch (...)
        {
            A a2;
            throw;
        }
    }
    catch (...)
    {
        A a3;
    }   
}

输出:

  

1

     

1

     

0

是否可以同时拥有两个或更多活动异常?

有什么例子吗?

1 个答案:

答案 0 :(得分:11)

是。从因处理另一个异常的堆栈展开而被调用的析构函数中抛出异常:

struct D
{
  ~D()
  {
    std::cout << std::uncaught_exceptions() << std::endl;
  }
};

struct E
{
  ~E()
  {
    try
    {
      D d_;
      throw 2;
    }
    catch(...)
    {
      std::cout << std::uncaught_exceptions() << std::endl;
    }
  }
};

int main()
{
  try
  {
    D d;
    E e;
    throw 1;
  }
  catch(...)
  {
  }
}
d仍然是活动异常时,将调用

1的析构函数。因此std::uncaught_exceptions()内的~d将为1。

对于e,将调用其析构函数,而1是一个活动异常。它的析构函数将被调用。它将构造一个D,然后再次抛出。但由于此时12都未被抓住,std::uncaught_exceptions()内的~d_将为2。

std::uncaught_exceptions的全部目的是检测这种情况。它允许您知道对象是否因堆栈展开或正常执行而被销毁。这可以让您知道是否应该进行不同类型的清理。考虑一个RAII对象,如果它因堆栈展开而被销毁,它将回滚一个事务。