Maison  >  Article  >  développement back-end  >  Comment fonctionne la règle de déplacement implicite lors du renvoi d'un objet nommé par valeur en C ?

Comment fonctionne la règle de déplacement implicite lors du renvoi d'un objet nommé par valeur en C ?

DDD
DDDoriginal
2024-11-04 06:20:02178parcourir

How does the Implicit Move Rule work when returning a named object by value in C  ?

Renvoi d'un objet nommé d'une classe par valeur et la règle de déplacement implicite

Lors du renvoi d'un objet d'une classe par valeur à partir d'une fonction, la règle de déplacement implicite vient en jeu. Cette règle régit le comportement du compilateur lors de la construction d'un objet temporaire pour contenir la valeur renvoyée.

Exemple 1 :

Considérez l'extrait de code suivant :

<code class="cpp">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(test&& s)noexcept {
        printf("test(test&& s)\n");
    }
    test& operator=(test e) {
        printf("test& operator=(test e)\n");
        return *this;
    }
};

test Some_thing() {
    test i;
    return i;
}

int main()
{
    Some_thing();
    return 0;
}</code>

Sortie :

test()
test(test&& s)

Dans cet exemple, la fonction Some_thing renvoie un objet nommé de la classe test, construit à l'aide du constructeur par défaut. Puisque le compilateur peut supprimer la copie en raison du NRVO (nommé optimisation de la valeur de retour), nous voyons la sortie du constructeur par défaut test() suivi du constructeur de déplacement implicite test(test&& s).

Exemple 2 :

Maintenant, modifions la fonction Some_thing pour utiliser le constructeur de copie à la place.

<code class="cpp">class test {
public:
    test(int y) {
        printf("test(int y)\n");
    }
    test() {
        printf("test()\n");
    }
    test(test& z) {
        printf("test(test&z)\n");
    }
    test(test&& s)noexcept {
        printf("test(test&& s)\n");  // Deleted this constructor
    }
    test& operator=(test e) {
        printf("test& operator=(test e)\n");
        return *this;
    }
};

test Some_thing() {
    test i;
    return i;
}

int main()
{
    Some_thing();
    return 0;
}</code>

Sortie :

test()
test(test&z)

Étonnamment, ce code se compile et s'exécute également, même bien qu'aucun constructeur de déplacement ne soit défini. En effet, la règle de déplacement implicite vérifie si l'expression i est « éligible au déplacement ». Dans ce cas, i est une variable locale, éligible au déplacement. Par conséquent, le compilateur peut toujours éluder l'opération de copie.

La règle de déplacement implicite

La règle de déplacement implicite se déclenche lorsque vous renvoyez un objet par valeur et que les conditions suivantes sont remplies :

  • L'expression représentant la valeur renvoyée est éligible au déplacement (c'est-à-dire qu'elle peut être déplacée sans violer les règles d'alias).
  • Aucun constructeur de copie ou de déplacement/opérateur d'affectation défini par l'utilisateur n'est viable. .

Conclusion

La règle de déplacement implicite fournit un moyen efficace et concis de renvoyer des objets par valeur. Il permet d'optimiser le code, de réduire les copies inutiles et d'améliorer les performances. Cependant, il est essentiel de comprendre ses limites et d’être conscient des problèmes potentiels qu’il peut entraîner s’il est utilisé sans mûre réflexion.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn