Maison > Article > développement back-end > Quand le constructeur Move est-il utilisé pour renvoyer des objets nommés par valeur en C ?
Renvoi d'un objet nommé par valeur à partir d'une fonction et d'une règle de déplacement implicite
Considérons une situation dans laquelle un objet d'une classe générique est renvoyé par valeur d’une fonction. Dans l'exemple 1 :
<code class="cpp">class test { public: test() { printf(" test()\n"); } test(test&& s) { printf(" test(test&& s)\n"); } test& operator=(test e) { printf(" test& operator=( test e)\n"); return *this; } }; test Some_thing() { test i; return i; }</code>
Le résultat est :
test() test(test&& s)
Dans cet exemple, le constructeur test() est appelé pour l'objet LValue que j'ai créé dans la fonction, et le déplacement Le constructeur test(test&& s) est appelé lorsque l'objet i est renvoyé par valeur, puisque l'expression return i est une référence rvalue.
Dans l'exemple 2, le constructeur de copie test(test& z) est fourni, mais le Le constructeur de déplacement n'est pas synthétisé par le compilateur :
<code class="cpp">class test { public: test() { printf(" test()\n"); } test(test& z) { printf(" test(test& z)\n"); } test& operator=(test e) { printf(" test& operator=( test e)\n"); return *this; } }; test Some_thing() { test i; return i; }</code>
La sortie reste la même que dans l'exemple 1 :
test() test(test& z)
Le constructeur de copie est utilisé car il n'y a pas de constructeur de déplacement disponible.
Dans l'exemple 3, le constructeur de déplacement est explicitement supprimé :
<code class="cpp">class test { public: test(test&& z) = delete; // Deleted move constructor test() { printf(" test()\n"); } test(test& z) { printf(" test(test& z)\n"); } test& operator=(test e) { printf(" test& operator=( test e)\n"); return *this; } }; test Some_thing() { test i; return i; }</code>
Essayer de compiler ce code entraînera une erreur, car le constructeur de déplacement supprimé signifie qu'aucune opération de déplacement ne peut être effectuée .
Dans l'exemple 4, même si le constructeur de déplacement est supprimé, le code se compile et s'exécute :
<code class="cpp">class test { public: test(test&& z) = delete; test() { printf(" test()\n"); } test(test& z) { printf(" test(test& z)\n"); } test& operator=(test e) { printf(" test& operator=( test e)\n"); return *this; } }; int main() { test u; test r(u); // Copy constructor is used return 0; }</code>
Sortie :
test() test(test& z)
Dans cet exemple, r (u) crée un nouvel objet r en copiant l'objet u. Le constructeur de déplacement n'est pas utilisé car il est supprimé, et le constructeur de copie est utilisé à la place.
Le point clé à retenir est que l'utilisation ou non du constructeur de déplacement dépend de la disponibilité d'un constructeur de déplacement viable et des règles de résolution de surcharge. Si le constructeur de déplacement est disponible et viable, il peut être utilisé pour initialiser la valeur renvoyée par une fonction, même si l'expression utilisée pour renvoyer la valeur est une LValue.
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!