據我了解,我們不能從 dtor 拋出例外,原因如下:“如果在‘堆疊展開’內拋出例外,則沒有明確的方法來處理‘嵌套展開’,因此‘從 dtor 拋出’被禁止。”。
讓我感到困惑的是,為了遵守上述規則,我們撰寫如下代碼:
#include <stdexcept>
#include <string>
#include <stdio.h>
void some_cleanup_stuff_that_may_throw();
class Bar
{
public:
virtual ~Bar(){
try {
some_cleanup_stuff_that_may_throw();
}
catch (std::exception& e){
fprintf(stderr, "Exception: %s from %s\n", e.what(), __FUNCTION__);
}
}
};
//{{ implementation of 'some_cleanup_stuff_that_may_throw'
void level1();
void level2();
void some_cleanup_stuff_that_may_throw()
{
level1();
}
void level1()
{
level2();
}
void level2()
{
throw std::runtime_error("Yes thrown when stack unwinding");
}
//}} implementation of 'some_cleanup_stuff_that_may_throw'
void Foo1()
{
Bar b1;
throw std::runtime_error("Let's start stack unwinding");
}
int main()
{
try {
Foo1();
}
catch (std::exception& e){
fprintf(stderr, "Exception: %s from %s\n", e.what(), __FUNCTION__);
}
return 0;
}
所以在某些情況下,“嵌套堆疊展開”是可能的。
我的問題是:“嵌套堆疊展開”何時“OK”?
uj5u.com熱心網友回復:
在堆疊展開程序中拋出例外是可以的。但是,從堆疊中展開的物件的解構式或例外處理機制(例如 catch 引數建構式)呼叫的任何其他函式中拋出例外會導致呼叫std::terminate.
在這里從函式中拋出應該意味著拋出的例外沒有被捕獲在其主體(或函式 try-catch 塊)內,并且實際上轉義了函式。
在您的示例中,離開解構式也不例外。所以沒有問題。
允許處理嵌套例外或處于堆疊展開程序中。一旦嵌套例外被捕獲、處理并且解構式完成,原始堆疊展開可以繼續呼叫下一個解構式再次向上移動堆疊。甚至還有用于此的 API。例如,您可以使用std::uncaught_exceptions()which 為您提供當前未捕獲的例外的數量。
C 運行時的實作只需要確保跟蹤當前活動的所有例外物件。
(我假設您對展開實作的確切實作細節并不真正感興趣。如果您是,請在問題中澄清這一點。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/489151.html
上一篇:Junit沒有得到自定義例外
下一篇:只知道名稱就拋出例外?
