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

问题描述 投票:8回答:1

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

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

有什么例子吗?

c++ exception exception-handling standards c++17
1个回答
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对象,如果它由于堆栈展开而被销毁,它将回滚一个事务。

© www.soinside.com 2019 - 2024. All rights reserved.