![](/img/trans.png)
[英]Lifetime extension of temporary objects: what is the full expression containing a function call?
[英]C++ temporary objects lifetime in a function call
當我們通過原始指針或通過引用將臨時智能指針管理的對象傳遞給函數時,標准是否保證對象的生命周期會延長到函數生命周期?
#include <iostream>
#include <memory>
struct A {
~A() {
std::cout << "~A()" << std::endl;
}
};
std::unique_ptr<A> makeA() {
return std::make_unique<A>();
}
void f(const A& a) {
std::cout << "f()" << std::endl;
}
int main() {
f(*makeA());
return 0;
}
我希望在從unique_ptr
獲得原始指針后銷毀由unique_ptr
管理的A
實例,因為它是一個臨時指針並且它沒有綁定到函數參數。 所以輸出可能是
~A()
f()
但是 gcc 和 clang 都讓它存活到函數結束,即輸出是
f()
~A()
所以看起來臨時智能指針並沒有被銷毀。
為什么A
實例(位於堆中)會一直存活到函數結束? 高度贊賞對標准的一些參考。
臨時變量會一直存在到創建它們的完整表達式結束(有一些生命周期延長例外),請參閱[class.temporary]/4 。
在您的情況下, std::unique_ptr<A>
類型的臨時感興趣的對象是由makeA()
創建的,而完整表達式 this 是f(*makeA());
的子表達式f(*makeA());
,所以臨時的生命周期將在那個分號處結束。
unique_ptr
管理的對象也只有在unique_ptr
本身被銷毀時才會被銷毀(這就是智能指針的目的)。
有關該規則的例外情況,請參閱標准的以下段落。
從標准, [class.temporary]/4
(強調我的)
臨時對象被銷毀作為評估完整表達式( [intro.execution] )(詞匯上)包含它們創建點的最后一步。 即使該評估以拋出異常結束,也是如此。 銷毀臨時對象的值計算和副作用僅與完整表達式相關,與任何特定子表達式無關。
這意味着,它與綁定到函數參數的臨時對象makeA()
,由makeA()
構造的臨時makeA()
在完整表達式結束之前不會被銷毀,其中包括函數f
的調用。
*makeA()
正在取消引用由調用makeA
創建的匿名臨時makeA
。
該標准保證匿名臨時對象在函數調用中幸存下來——換句話說,當程序控制到達語句末尾時,在概念上調用~A
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.