C ++ уничтожение временного объекта в выражении - PullRequest
2 голосов
/ 03 декабря 2009

С учетом следующего кода:

#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 ]

13 голосов
/ 03 декабря 2009

Временные объекты уничтожаются как последний шаг в оценке полного выражения (1.9), которое (лексически) содержит точку, где они были созданы. [12.2 / 3]

5 голосов
/ 03 декабря 2009

12.2 Временные объекты, пункт 3: «Временные объекты уничтожаются как последний шаг в оценке полного выражения (1.9), которое (лексически) содержит точку, где они были созданы.»

1.9 Выполнение программы, пункт 12: «Полное выражение - это выражение, которое не является подвыражением другого выражения.»

1 голос
/ 03 декабря 2009

Поскольку существует конструктор, который может принимать аргумент, передаваемый в функцию 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
0 голосов
/ 03 декабря 2009

f(42) создает безымянный implicit_t неявно. Он живет до тех пор, пока он содержит область видимости, как любая переменная auto. Естественно, d'tor вызывается на return 0; из main().

...