Ein benanntes Objekt nach Wert von einer Funktion und einer impliziten Verschiebungsregel zurückgeben
Stellen Sie sich eine Situation vor, in der ein Objekt einer generischen Klasse von zurückgegeben wird Wert aus einer Funktion. In Beispiel 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>
Die Ausgabe lautet:
test() test(test&& s)
In diesem Beispiel wird der Konstruktor test() für das LValue-Objekt aufgerufen, das ich in der Funktion erstellt habe, und die Verschiebung Der Konstruktor test(test&& s) wird aufgerufen, wenn das Objekt i als Wert zurückgegeben wird, da der Ausdruck return i eine R-Wert-Referenz ist.
In Beispiel 2 wird der Kopierkonstruktor test(test& z) bereitgestellt, aber der Der Verschiebungskonstruktor wird vom Compiler nicht synthetisiert:
<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>
Die Ausgabe bleibt dieselbe wie in Beispiel 1:
test() test(test& z)
Der Kopierkonstruktor wird verwendet, da kein Verschiebungskonstruktor verfügbar ist.
In Beispiel 3 wird der Verschiebungskonstruktor explizit gelöscht:
<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>
Der Versuch, diesen Code zu kompilieren, führt zu einem Fehler, da der gelöschte Verschiebungskonstruktor bedeutet, dass keine Verschiebungsoperation ausgeführt werden kann .
In Beispiel 4 wird der Code kompiliert und ausgeführt, obwohl der Verschiebungskonstruktor gelöscht wurde:
<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>
Ausgabe:
test() test(test& z)
In diesem Beispiel ist r (u) erstellt ein neues Objekt r durch Kopieren des Objekts u. Der Verschiebungskonstruktor wird nicht verwendet, da er gelöscht wurde, und stattdessen wird der Kopierkonstruktor verwendet.
Die wichtigste Erkenntnis ist, dass die Verwendung des Verschiebungskonstruktors von der Verfügbarkeit eines brauchbaren Verschiebungskonstruktors und den Regeln dafür abhängt Überlastauflösung. Wenn der Verschiebungskonstruktor verfügbar und funktionsfähig ist, kann er zum Initialisieren des von einer Funktion zurückgegebenen Werts verwendet werden, auch wenn der zur Rückgabe des Werts verwendete Ausdruck ein LValue ist.
Das obige ist der detaillierte Inhalt vonWann wird der Move-Konstruktor zum Zurückgeben benannter Objekte nach Wert in C verwendet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!