是否可以同时有两个或多个活动异常?
Is it possible to have two or more active exceptions at the same time?
C++17引入了一个新函数std::uncaught_exceptions
:
Detects how many exceptions have been thrown or rethrown and not yet
entered their matching catch clauses.
以下代码:
#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
是否可以同时有两个或多个活跃异常?
有例子吗?
是的。从因堆栈展开处理另一个异常而调用的析构函数中抛出异常:
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
,然后再次抛出。但是由于此时 1
和 2
都没有被捕获,所以 ~d_
内部的 std::uncaught_exceptions()
将是 2.
std::uncaught_exceptions
的全部目的就是检测这种情况。它可以让您知道对象是由于堆栈展开还是通过正常执行而被销毁。这让您知道是否应该进行不同类型的清理。考虑一个 RAII 对象,如果它由于堆栈展开而被销毁,它将回滚事务。
C++17引入了一个新函数std::uncaught_exceptions
:
Detects how many exceptions have been thrown or rethrown and not yet entered their matching catch clauses.
以下代码:
#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
是否可以同时有两个或多个活跃异常?
有例子吗?
是的。从因堆栈展开处理另一个异常而调用的析构函数中抛出异常:
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
,然后再次抛出。但是由于此时 1
和 2
都没有被捕获,所以 ~d_
内部的 std::uncaught_exceptions()
将是 2.
std::uncaught_exceptions
的全部目的就是检测这种情况。它可以让您知道对象是由于堆栈展开还是通过正常执行而被销毁。这让您知道是否应该进行不同类型的清理。考虑一个 RAII 对象,如果它由于堆栈展开而被销毁,它将回滚事务。