簡體   English   中英

C ++中拋出異常的生命周期

[英]Lifecycle of thrown exceptions in C++

請考慮以下簡單的C ++代碼:

void foo() {
    throw(my_exception());
}

void check_exc(const my_exception &exc) {
    /* Do stuff with exc */
}

void bar() {
    try {
        foo();
    } catch(const my_exception &exc) {
        check_exc(exc);
    }
}

bar的異常處理程序中, exc引用的異常如何仍然存在,看看它是如何在foo的堆棧幀中分配的? 在異常處理程序運行時,該幀是否應該被解除,並且在那里分配的任何值都已經被認為是死的? 特別是因為我明確地調用了另一個需要堆棧空間的函數。

作為一名試圖學習C ++的C程序員,我在這里誤解了什么? 這些不同的值實際上存在於內存中,更確切地說是什么?

在throw-expression中創建的臨時用於初始化異常對象本身,(引用標准)“以未指定的方式分配”。 該對象(至少)持續到處理異常為止,因此處理程序對它的引用在處理程序或從處理程序調用的任何函數中都是有效的。

例外是按價值拋出

也就是說,復制指定的對象(可能是切片,與任何復制初始化一樣)或移動。

您可以通過例如catch子句的引用參數引用的異常對象不會在原始拋出代碼的堆棧幀中分配,而是以“未指定的方式”分配。


在C ++ 11中,可以通過本質上共享的所有權智能指針std::exception_ptr引用異常對象的要求來限制異常對象可以分配的可能方式(在運行時庫內部)。

共享所有權的可能性意味着在C ++中,異常對象可以具有超出完成的異常處理的有保證的生命周期。

這主要是為了支持通過非異常感知的C代碼傳遞異常,並且為了傳遞嵌套的異常信息。

實施因平台而異。 生命周期比人們想象的更復雜,因為throw語句開始在foo()的堆棧幀中執行。

異常對象可能會獲得副本並重新分配,或者catch塊可能在foo頂部的框架中執行,但是帶有指向條形框架的指針以引用條形變量。

他,

這條線

 throw(my_exception()) 

生成my_exception類型的新對象。 您可以指定所需的任何內容(int,enums,char *或類)。 當然,類更有意義,因為您可以為其定義其他數據。

在此之后,將清理整個堆棧並終止所有遞歸,直到它到達第一個try / catch塊。 那個例外仍然存在。 catch塊中的代碼就像實現if / else塊一樣,只是更聰明一些。

干杯,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM