簡體   English   中英

通過引用,臨時,終身問題捕獲異常對象

[英]catching exception objects by reference, temporaries, lifetime issues

請考慮以下代碼:

#include <iostream>
#include <stdexcept>

void foo()
{
    throw std::runtime_error("How long do I live?");
}

int main()
{
    try
    {
        foo();
    }
    catch (std::runtime_error& e)
    {
        std::cout << e.what() << std::endl;
    }
}

為什么我可以通過引用捕獲異常,不是std::runtime_error("How long do I live?")一個右值?

為什么異常對象在catch塊中仍然存在?

究竟拋出異常對象存儲在哪里? 他們的一生是幾歲?

在C ++標准中,第15.1.4段:

除非在3.7.3.1中指出,否則將以未指定的方式分配要拋出的異常的臨時副本的內存。 只要存在針對該異常執行的處理程序,臨時就會持續存在 特別是,如果處理程序通過執行throw而退出; 語句,將控制權傳遞給另一個處理程序以獲得相同的異常,因此臨時保留。 當為異常執行的最后一個處理程序以throw以外的任何方式退出時; 臨時對象被銷毀,實現可能會釋放臨時對象的內存; 任何這種解除分配都是以未指明的方式完成的。 在銷毀處理程序中的exception-declaration中聲明的對象后立即發生破壞。

請注意,在C ++ - 標准對話中,處理程序表示具有正確參數類型的catch塊。

拋出的異常不是臨時的 - 編譯器生成的異常代碼會保留它的永久副本。 所以你可以將它綁定到非const引用。

[edit]我只是檢查標准,它實際上是指臨時副本。 但是,臨時的生命周期保證至少與異常處理程序的生命周期一樣長。

正如尼爾所說,內部編譯器魔法正在進行中。 另外,請注意允許編譯器創建任意數量的異常對象副本

感謝您試圖了解該語言的細節。 與此同時,恕我直言,這是更為重要的是了解你為什么趕通過引用異常(和值,把它扔),比為什么。

人們通常使用異常類的層次結構,並且通過引用捕獲允許您在不需要單獨處理單個異常類型時利用多態性並捕獲基類的異常。 如果您無法通過引用捕獲,則必須為可以在try子句中拋出的每種可能類型的異常編寫catch子句。

暫無
暫無

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

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