给出以下代码:
#include <iostream>
struct implicit_t
{
implicit_t(int x) :
x_m(x)
{
std::cout << "ctor" << std::endl;
}
~implicit_t()
{
std::cout << "dtor" << std::endl;
}
int x_m;
};
std::ostream& operator<<(std::ostream& s, const implicit_t& x)
{
return s << x.x_m;
}
const implicit_t& f(const implicit_t& x)
{
return x;
}
int main()
{
std::cout << f(42) << std::endl;
return 0;
}
我得到以下输出:
ctor
42
dtor
虽然我知道这是正确的,但我不确定为什么。是否有任何有stdc ++知识的人可以向我解释一下?
答案 0 :(得分:13)
临时对象作为评估全表达式(1.9)的最后一步被销毁,该表达式(词法上)包含创建它们的点。 [12.2 / 3]
答案 1 :(得分:5)
12.2临时对象,第3节:“作为评估全表达式(1.9)的最后一步,临时对象被销毁(词法)包含创建它们的点。”
1.9程序执行,第12节:“完整表达式是一个不是另一个表达式的子表达式的表达式。”
答案 2 :(得分:1)
由于有一个构造函数可以接受传递给F()函数的参数,因此编译器会在将参数放入堆栈之前动态创建对象。从下面的反汇编中可以看出。默认情况下,字面数字被视为整数,因此可以接受转换。
001115C5 call implicit_t::implicit_t (11112Ch)
001115CA mov dword ptr [ebp-4],0
001115D1 mov esi,esp
001115D3 mov eax,dword ptr [__imp_std::endl (11A308h)]
001115D8 push eax
001115D9 lea ecx,[ebp-0D4h]
001115DF push ecx
001115E0 call f (111113h)
您的临时对象会挂起,直到对表达式进行全面评估。如果你为你的函数添加另一个调用,这可以更明显。
int main()
{
std::cout << f(42) << std::endl;
std::cout <<f(80) << std::endl;
return 0;
}
其输出为
ctor
42
dtor
ctor
80
dtor
答案 3 :(得分:-3)
f(42)
隐含地构造一个未命名的implicit_t
。它存在于包含范围的持续时间内,就像任何auto
变量一样。当然,在return 0;
main()
的{{1}}上调用d'tor。