#include "stdio.h"
class C {
public:
~C() { printf("~C\n"); }
};
int I(const C& c) { printf("I\n"); return 0; }
void V(int i) { printf("V\n"); }
int main() {
V(I(C()));
return 0;
}
I
V
~C
我本來期望:
I
~C
V
#include "stdio.h"
class C {
public:
~C() { printf("~C\n"); }
};
int I(const C& c) { printf("I\n"); return 0; }
void V(int i) { printf("V\n"); }
int main() {
V(I(C()));
return 0;
}
I
V
~C
我本來期望:
I
~C
V
V(I(C()));
C()
創建一個臨時其仍然存在直到充分表達的完成,和充分表達的完成是;
(即分號)。這就是爲什麼你看到我認爲的輸出是明確的。
第§12.2/ 3從標準讀取,
[...]臨時對象評估 全表達(1.9)破壞作爲最後的步驟,(詞彙)包含它們的創建點。即使評估以拋出異常結束,情況也是如此。
只是強調,在這個例子中,臨時的壽命有無關的功能I()
的參考或const引用參數。即使I()
的簽名是:
int I(C c); //instead of : int I(const C & c);
臨時會堅持,直到全表達的完成,你會看到完全相同相同的輸出。
爲什麼?臨時的生活直到完整的表達式結束。
如果在僅評估直接包含的表達式後臨時數據可能會被合法銷燬,那麼該堆棧空間可用於評估表達式的其餘部分。鑑於歷史上關於表達評估的寬鬆規則,這似乎是合理的。 – BCS 2011-04-20 16:11:15
您所看到的行爲是由標準強制要求的行爲:在完整表達式創建結束時銷燬臨時對象。
從歷史上看,可以看到另一種行爲(並且在某些編譯器中仍然可用):在塊的末尾銷燬。在你的情況下,它不會造成任何影響,因爲它會進一步推遲破壞。
充分表達之前V
的調用返回已完全評估。當V
已經返回時,它會打印它的東西(從V
返回之前有一個順序點)。
臨時C()
僅在評估完整的完整表達式後才銷燬。
你爲什麼期待?如果我()返回const C&?臨時的生命週期至少要持續嵌入表達式的持續時間。 – mcmcc 2011-04-20 16:01:19
@mcmcc:C()嵌入的表達式是I(C())'。整行是一個表達式*語句*。 – BCS 2011-04-20 16:05:50
查看已更新的答案。現在它完全正確。 – Nawaz 2011-04-20 16:31:52