"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Quando o retorno de um objeto por valor aciona um construtor de movimento?

Quando o retorno de um objeto por valor aciona um construtor de movimento?

Publicado em 2024-11-16
Navegar:124

When Does Returning an Object by Value Trigger a Move Constructor?

Retornando um objeto de uma classe de uma função por valor

Considere o caso em que você retorna um objeto de uma classe de uma função por valor. Nesse cenário, o objeto retornado normalmente é considerado um lvalue, o que significa que possui um nome e um endereço na memória. No entanto, certas circunstâncias podem fazer com que o objeto retornado seja tratado como um rvalue, um objeto temporário sem nome ou endereço.

A regra de movimentação implícita

C define uma regra de movimentação implícita que pode ser aplicada ao retornar um objeto por valor. Esta regra afirma que se as seguintes condições forem atendidas:

  • A expressão retornada é um xvalue (uma expressão que denota um objeto temporário que não é um lvalue).
  • A classe do o objeto retornado tem um construtor de movimentação.
  • O construtor de movimentação está acessível.

Nesses casos, o construtor de movimentação será invocado em vez do construtor de cópia. Esse comportamento tem como objetivo otimizar o desempenho, evitando cópias desnecessárias.

Exemplo 1

Neste exemplo, o objeto retornado i é um lvalue, portanto, o construtor de cópia test( const test& z) é invocado:

class test {
public:
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(const test& z) { printf("test(const test&z)\n"); }
};
test Some_thing() {
    test i;
    return i;
}

Saída:

test()
test(const test&z)

Exemplo 2

No entanto, no exemplo a seguir, o objeto retornado i é tratado como um xvalue e o construtor de movimentação test( test&& s) é invocado porque o objeto é temporário e o construtor de movimentação é viável:

class test {
public:
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(test&& s) { printf("test(test&& s)\n"); }
};
test Some_thing() {
    test i;
    return i;
}

Saída:

test()
test(test&& s)

Exemplo 3

Se um construtor de movimentação não for fornecido ou for explicitamente excluído, a regra de movimentação implícita não poderá ser aplicada, e o o programa falhará ao compilar:

class test {
public:
    test(test&& z) = delete;
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(const test& z) { printf("test(const test&z)\n"); }
};
test Some_thing() {
    test i;
    return i;
}

Conclusão

Ao retornar um objeto por valor, a regra de movimentação implícita pode ser aplicada sob condições específicas, resultando na invocação do construtor de movimentação. Compreender esse comportamento é crucial para otimizar o código e evitar erros de compilação.

Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3