Maison  >  Article  >  développement back-end  >  Quand le retour d'un objet par valeur déclenche-t-il un constructeur de déplacement ?

Quand le retour d'un objet par valeur déclenche-t-il un constructeur de déplacement ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-04 08:51:30324parcourir

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

Renvoyer un objet d'une classe à partir d'une fonction par valeur

Considérons le cas où vous renvoyez un objet d'une classe à partir d'une fonction par valeur. Dans ce scénario, l'objet renvoyé est généralement considéré comme une lvalue, ce qui signifie qu'il possède un nom et une adresse en mémoire. Cependant, certaines circonstances peuvent conduire à ce que l'objet renvoyé soit traité comme une rvalue, un objet temporaire sans nom ni adresse.

La règle de déplacement implicite

C définit une règle de déplacement implicite qui peut s'appliquer lors du renvoi d'un objet par valeur. Cette règle stipule que si les conditions suivantes sont remplies :

  • L'expression renvoyée est une xvalue (une expression désignant un objet temporaire qui n'est pas une lvalue).
  • La classe du l'objet renvoyé a un constructeur de déplacement.
  • Le constructeur de déplacement est accessible.

Dans de tels cas, le constructeur de déplacement sera invoqué à la place du constructeur de copie. Ce comportement vise à optimiser les performances en évitant les copies inutiles.

Exemple 1

Dans cet exemple, l'objet renvoyé i est une lvalue, donc le constructeur de copie test( const test& z) est invoqué :

<code class="cpp">class test {
public:
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(const test&amp; z) { printf("test(const test&amp;z)\n"); }
};
test Some_thing() {
    test i;
    return i;
}</code>

Sortie :

test()
test(const test&amp;z)

Exemple 2

Cependant, dans l'exemple suivant, le l'objet renvoyé i est traité comme une valeur x et le constructeur de déplacement test(test&& s) est invoqué car l'objet est temporaire et le constructeur de déplacement est viable :

<code class="cpp">class test {
public:
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(test&amp;&amp; s) { printf("test(test&amp;&amp; s)\n"); }
};
test Some_thing() {
    test i;
    return i;
}</code>

Sortie :

test()
test(test&amp;&amp; s)

Exemple 3

Si un constructeur de déplacement n'est pas fourni ou est explicitement supprimé, la règle de déplacement implicite ne peut pas être appliquée et le programme ne parviendra pas à compiler :

<code class="cpp">class test {
public:
    test(test&amp;&amp; z) = delete;
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(const test&amp; z) { printf("test(const test&amp;z)\n"); }
};
test Some_thing() {
    test i;
    return i;
}</code>

Conclusion

Lors du retour d'un objet par valeur, la règle de déplacement implicite peut être appliquée dans des conditions spécifiques, ce qui entraîne l'invocation du constructeur de déplacement. Comprendre ce comportement est crucial pour optimiser le code et éviter les erreurs de compilation.

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