Move Semantics ist ein Mechanismus in C++, der es ermöglicht, Ressourcen effizient zwischen Objekten zu übertragen, anstatt sie zu kopieren. Mit der Einführung von C++11 wurden move-Konstruktoren und Zuweisungsoperatoren eingeführt, die es Objekten ermöglichen, ihre Ressourcen an ein anderes Objekt zu übergeben, ohne die Kosten einer Kopie zu verursachen.
std::move verwandelt das übergebene Objekt in einen rvalue-Verweis und signalisiert, dass seine Ressourcen sicher verschoben werden können. std::forward wird in Templates verwendet, um den Werttyp (lvalue/rvalue) beim Weitergeben zu erhalten.
#include <string> #include <vector> #include <iostream> std::vector<std::string> getNames() { std::vector<std::string> v = {"Alice", "Bob", "Charlie"}; return v; // Hier werden Move Semantics wirksam } int main() { std::vector<std::string> names = getNames(); // Hier werden die Inhalte von getNames() ohne überflüssige Kopierungen verschoben }
Was ist der Unterschied zwischen std::move und einem Move-Konstruktor? Wenn man std::move schreibt, wird das Objekt immer verschoben?
Antwort:
std::move ist lediglich eine Umwandlung in einen rvalue-Verweis, es führt nicht selbst die Verschiebung durch. Die Verschiebeoperation wird nur ausgeführt, wenn tatsächlich ein implementierter Move-Konstruktor/Zuweisungsoperator vorhanden ist. Andernfalls findet eine Kopie statt.
struct A { A() = default; // kein Move-Konstruktor A(const A&) { std::cout << "Kopie! "; } }; A a1; A a2 = std::move(a1); // Es erfolgt eine Kopie, keine Verschiebung
Geschichte
-In einem der Finanzsysteme wurde die Arbeit mit Zeichenfolgen optimiert, indem Kopien durch std::move ersetzt wurden, aber die Struktur hatte keine implementierten Move-Konstruktoren. Die Kopie blieb erhalten, die Leistung verbesserte sich nicht, und es entstand ein falsches Vertrauen in die Beschleunigung des Codes.
Geschichte
-Ein Entwickler führte std::move() auf einer Variablen aus, die er nach der Verschiebung weiterhin verwendete. Die Daten befanden sich in einem inkonsistenten Zustand, die Anwendung stürzte gelegentlich ab.
Geschichte
-Im serverseitigen Bibliothekscode wurden temporäre Objekte durch const-Referenz entgegengenommen und anschließend wurde std::move() versucht, während eine Verschiebung erwartet wurde. Das Ergebnis war eine Kopie, ineffiziente Arbeit und ein Anstieg der Latenzen bei hoher Last.