destruição de C ++ objecto temporário numa expressão
-
11-09-2019 - |
Pergunta
Dado o seguinte código:
#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;
}
Eu recebo o seguinte resultado:
ctor
42
dtor
Enquanto eu sei que isso é correto, eu não estou certo por . Existe alguém com STDC conhecimento ++ que pode explicar isso para mim?
Solução
Objetos temporários são destruídos como o último passo na avaliação da expressão completa (1,9) que (lexically) contém o ponto onde eles foram criados. [12.2 / 3]
Outras dicas
12.2 objetos temporários, cláusula 3: "Objetos temporários são destruídos como o último passo na avaliação da expressão completa (1,9) que (lexically) contém o ponto onde eles foram criados"
1.9 A execução do programa, inciso 12: "A-plena expressão é uma expressão que não é uma sub-expressão de outra expressão"
Uma vez que existe um construtor que pode aceitar o argumento passado para a função F (), o compilador cria o objeto em tempo real antes de colocar os argumentos na pilha. Como pode ser ver na desmontagem abaixo. números literais são tratados por defeito como ints para que haja uma conversão aceitável.
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)
Seus trava temporário de objetos ao redor até que a expressão é totalmente avaliada. isso pode ser feito mais evidente se você adicionar outra chamada para a sua função.
int main()
{
std::cout << f(42) << std::endl;
std::cout <<f(80) << std::endl;
return 0;
}
que tem uma saída de
ctor
42
dtor
ctor
80
dtor
f(42)
constrói uma implicit_t
sem nome implicitamente. Ele vive para a duração do seu escopo contendo, assim como qualquer variável auto
faria. Naturalmente, o d'tor é chamado em return 0;
de main()
.