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:
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.
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