Pergunta

Para este programa

#include <iostream>
using std::cout;

struct C 
{
    C() { cout << "Default C called!\n"; }
    C(const C &rhs) { cout << "CC called!\n"; }
};

const C f()
{
    cout << "Entered f()!\n";
    return C();
}

int main()
{
    C a = f();
    C b = a;

    return 0;
}

a saída que eu vejo é:

Entered f()!
Default C called!
CC called!

Desde f() é a devolver o valor, ele deve retornar um temporário.Como T a = x; é T a(x);, não é chamar o construtor de cópia para a construção de a, com o temporário no passado como argumento?

Foi útil?

Solução

Desde f() é a devolver o valor, ele deve retornar um temporário.Como T a = x; é T a(x);, não é chamar o construtor de cópia para a construção de a, com o temporário no passado como argumento?

Procurar Valor de Retorno de Otimização.Esta é ativada por padrão.Se você estiver no Windows, usando MSVC 2005+ você pode usar /Od para desligar esta opção e obter o resultado desejado (ou -fno-elide-constructors no GCC).Também, para ver MSVC este artigo.

12.8 Copiar objectos de classe

15 Quando determinados critérios forem atendidos, uma a implementação é permitido omitir o cópia de construção de um objeto de classe, mesmo se o construtor de cópia e/ou destruidor do objeto tem um lado efeitos.Em tais casos, o implementação trata a origem e o alvo da omitido operação de cópia simplesmente como duas formas diferentes de referindo-se ao mesmo objeto, e a a destruição do objeto ocorre em o posterior das vezes quando as duas os objetos teriam foi destruída sem a otimização.115 Este elision de cópia operações é permitida a seguintes circunstâncias (que pode ser combinado para eliminar vários cópias):

em uma instrução return em uma função com uma classe de tipo de retorno, quando a expressão é o nome de um não-volátil automático de objetos com o mesmo cv-não qualificado como o tipo de tipo de retorno de função, a cópia a operação pode ser omitido por construção automática de objeto diretamente para o retorno da função valor — em um lance de expressão, quando o operando é o nome de um não-volátil automático de objetos, o operação de cópia do operando para o objeto de exceção (15.1) pode ser omitido ao construir o objeto automática diretamente para o objeto de exceção

— quando uma classe temporária objeto que tem não foi vinculado a uma referência (12.2) deve ser copiado para um objeto de classe com o mesmo cv-não qualificados tipo, a cópia a operação pode ser omitido por construindo o objeto temporário diretamente para o destino da omitido cópia

— quando o exceção-declaração de uma exceção manipulador (Cláusula 15) declara um objeto do mesmo tipo (exceto para cv-qualificação) como exceção objeto (15.1), a operação de cópia pode ser omitido, por tratar o exceção de declaração como um alias para o objeto de exceção se o significado de o programa será inalterado, exceto para a execução de construtores e destruidores para o objeto declarado por a exceção de declaração.

Nota:Ênfase minha

Outras dicas

Este é um exemplo de Otimização de valor de retorno (RVO) Recursos que seu compilador suporta.

Um construtor de cópia pode não ser chamado quando você retornar por valor.

Usar -fno-elide-constructors Opção no GCC para desativar esse recurso.

Eu acredito que é chamado Otimização do valor de retorno.

Eu presumo quando f() retorna C Objeto O objeto é alocado no espaço da pilha do método de chamada, portanto, nenhuma cópia é necessária para inicializar C a. Isto é seu default C called.

C b = a

Isso causa um construtor de cópia, daí o seu CC called.

BTW, o exemplo do Wiki se parece semelhante ao seu código.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top