2010-12-10 7 views
0

Okay, ich habe gelesen über rvalues ​​und sie scheinen wie eine gute Idee, aber etwas stört mich über sie. Insbesondere die Behauptung, dass move es erlaubt, Ressourcen zu stehlen und das Kopieren zu vermeiden.rvalues ​​C++ 0x und Umzug auf den Haufen

Ich verstehe, dass Bewegung funktioniert und vermeidet kopieren für alles, was auf dem Stapel passiert, aber schließlich die meisten Sachen auf dem Stapel getan erbringt einen Wert, den wir in den Haufen kopiert werden wollen und das ist, wo ich nicht denke Bewegung funktioniert.

Unter der Annahme, dass eine Bewegung int Zuweisungsoperator hat, mit dem folgenden Code:

struct Foo 
{ 
int x; 
}; 

void doIt() 
{ 
Foo* f = new Foo(); 
f->x = (2 + 4); 
} 

also in diesem Beispiel ist der R-Wert aus (2 + 4), kann angenommen werden, bewegt über> f- x anstelle von kopiert. OK großartig. Aber f und folglich ist f-> x auf dem Haufen und dieser rvalue ist auf dem Stapel. Es scheint unmöglich, eine Kopie zu vermeiden. Sie können nicht einfach f-> x auf den Speicher des rvalue zeigen. Dieser Wert wird weggeweht, sobald es endet. Eine Kopie scheint notwendig.

Also habe ich Recht, dass eine Kopie gemacht wird? Oder irre ich mich? Oder habe ich das rvalue-Konzept komplett falsch verstanden?

+1

Es scheint, dass Sie etwas falsch verstehen. Das Bewegen ist keine Magie und es gibt keinen schnelleren Weg, einen int-Wert zu erhalten als das Zuweisen/Kopieren. – UncleBens

+0

@UncleBens Nun, ich versuche das nur zu bestätigen. Ich lese weiterhin rvalues ​​Dinge schneller machen und kopieren zu vermeiden. Aber wie in meinem Beispiel versuche ich zu bestätigen, dass das Kopieren tatsächlich erforderlich ist und rvalues ​​nur in bestimmten Fällen helfen. – anio

+0

Das Verschieben von Objekten von Skalartypen entspricht dem Kopieren von Objekten. Moving wird mit komplexeren Typen interessant.Was genau passiert, wenn Sie diese verschieben, liegt beim Klassen-Designer. Sie steuern dieses Verhalten, indem Sie Ihren eigenen Move-Konstruktor definieren. – sellibitze

Antwort

5

In diesem Fall würde es wahrscheinlich eine Kopie machen, aber da das Objekt nur eine int enthält, ist das nicht wirklich ein großes Problem.

Die Zeiten, die Sie interessieren, sind im Allgemeinen, wenn das Objekt einen Zeiger auf einige Daten enthält, die auf dem Heap zugeordnet sind (unabhängig davon, wo das Objekt selbst zugeordnet ist). In diesem Fall lohnt es sich, das Zuweisen einer neuen Kopie dieser Daten zu vermeiden (und da es sich auf dem Heap befindet, selbst wenn das Objekt selbst auf dem Stapel liegt, können Sie es unabhängig davon verschieben, wo sich das Objekt selbst befindet).

+0

Gut Punkt. Move kann zum Stehlen von Ressourcen von einem Heapspeicherort zu einem anderen verwendet werden. Also können wir Stapel-zu-Stapel-Züge haben. Und Heap-zu-Heap-Bewegungen. Aber keine Stack-to-Heap-Bewegungen. Was ich erwartet habe. – anio

+1

Sicher können Sie Objekte von Stapel zu Haufen und umgekehrt verschieben. Ein move-enabled-Typ interessiert sich normalerweise nicht dafür, wo er sich befindet. Das Speicherkonzept ist orthogonal zur Bewegungssemantik. – sellibitze

1

Um. Lokale Variablen befinden sich auf dem Stapel. Dieser rvalue von dir wird auf 6 optimiert und die resultierende binäre wird höchstwahrscheinlich eine mov [dest], 6 darin haben.

3

Mein Verständnis ist, dass bewegt sich nicht das Gegenteil des Kopierens ist: bewegen vorzuziehen ist, weil in den meisten Fällen wird es eine flache Kopie (anstelle eines tiefe Kopie) implementieren.

Wenn ein Objekt einen Zeiger auf eine Ressource enthält, kopiert eine flache Kopie den Zeiger, während eine tiefe Kopie die Daten kopiert, auf die der Zeiger zeigt. Es wird immer kopiert, die Frage ist: "Wie tief müssen wir gehen".

Ihr Beispiel beinhaltet nur ein int: es gibt nicht so etwas wie eine flachen oder tief Kopie eines int, so ist es hier nicht relevant. Sie haben also recht zu glauben, dass Verschieben nur dann sinnvoll ist, wenn dynamisch zugewiesene Ressourcen beteiligt sind.

+0

Moving ist sicherlich nicht * begrenzt * auf seichte Kopien. Was ein Move-Konstruktor tut, hängt vom Klassen-Designer ab. – sellibitze