[英]Delete throwing destructor called from destructor
我了解C ++中的當前規則表明:
如果析構函數由於異常而在已經展開堆棧時拋出了異常,則調用
std::terminate
。
在探究規則為何如此時,我遇到了以下代碼中描述的情況。
X
的析構函數拋出。
Y
刪除其自己的析構函數中的X
因此, Y
的析構函數拋出。
我不清楚Y
拋出(3.)的事實是否應該觸發標准規則的std::terminate
。 我希望它不應該如此,並且針對gcc
測試按我希望的那樣運行。
熟悉標准法律法規的人可以澄清這一點嗎? (3.)是否應該觸發std::terminate
?
#include <iostream>
struct X {
~X() noexcept(false) {
std::cout << "Destroying X\n";
throw std::runtime_error("Exception");
}
};
struct Y {
X * x_;
explicit Y(X * x) : x_{x} { }
~Y() noexcept(false) {
std::cout << "Destroying Y\n";
delete x_;
}
};
int main() {
try {
Y y(new X());
std::cout << "Living\n";
}
catch (const std::exception & e) {
std::cout << "Caught " << e.what() << '\n';
}
}
使用帶有--std=c++17
g ++版本5.4.0-6ubuntu1〜16.04.9,我得到:
Living
Destroying Y
Destroying X
Caught Exception
該標准在[except.terminate] p1.4中說 :
- 當堆棧展開期間對象的銷毀因引發異常而終止時,或者
2)發生是因為y
超出范圍。 1)引發異常,這開始堆棧展開。 在堆棧展開期間,更具體地說,在破壞Y
同時-2)。 它拋出一個異常,因此滿足了這一點,並調用了std::terminate
。
除了要注意的一點: 堆棧展開期間 ,這正是您正在執行的代碼。 范圍結束時不會發生堆棧展開,僅當引發異常並超出引發它的當前范圍時才會發生堆棧展開。
Y
沒有因為異常而被破壞。 加throw 1;
查看對std::terminate
的調用。
因此,該子句不適用,您的代碼確實有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.