C ++破坏表达式中的临时对象

时间:2009-12-03 01:28:31

标签: c++ constructor destructor temporary-objects

给出以下代码:

#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 ++知识的人可以向我解释一下?

4 个答案:

答案 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。