"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > 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 ?

Publié le 2024-11-16
Parcourir:100

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 entraîner le traitement de l'objet renvoyé 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 retour d'un objet par valeur. Cette règle stipule que si les conditions suivantes sont remplies :

  • L'expression renvoyée est une valeur x (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 est destiné à 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é :

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;
}

Sortie :

test()
test(const test&z)

Exemple 2

Cependant, dans l'exemple suivant, 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 :

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;
}

Sortie :

test()
test(test&& 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 le programme ne parviendra pas à compiler :

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;
}

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.

Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3