#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