2016-06-07 7 views
4

Verstehe ich es richtig, dass die C++ 14 Standardbibliothek Bewegungssemantik verwendet? Mit anderen Worten, kann ich sicher sein, dass ich eine Bewegung statt eine Kopie in dem folgende Programm verwenden:Woher weiß ich, ob ich kopieren oder verschieben?

#include <iostream> 
#include <string> 
#include <vector> 

using namespace std::string_literals; 

std::vector<std::string> greeting() 
{ 
    std::vector<std::string> vs {"hello"s, "world"s}; 
    return vs; 
} 

int main() 
{ 
    std::vector<std::string> s = greeting(); 
    std::cout << s[0] << " " << s[1] << "\n" ; 
} 

Gibt es eine Möglichkeit kann ich überprüfen?

Wie etwa in folgendem Beispiel:

#include <iostream> 
#include <string> 
#include <vector> 

using namespace std::string_literals; 

class Greeting { 
    public: 
    std::string first, second; 
    Greeting() { first = "hello"s ; second = "world"s ;}; 
}; 

Greeting greetingc() 
{ 
    Greeting g; 
    return g; 
} 

int main() 
{ 
    Greeting g = greetingc(); 
    std::cout << g.first << " " << g.second << "\n" ; 
} 

verschieben oder kopieren?

+0

Wo genau möchten Sie überprüfen? Welche Codezeile sollte eine Bewegung sein? – rubenvb

+0

@rubenvb Ich meine, wenn die Return-Anweisung aus Gruß (0 oder Greetingc()) aufgerufen wird, was macht das Programm: Kopiert es das Objekt (eine möglicherweise teure Operation) oder bewegt es das Objekt (eine billige Operation) – blippy

+0

Wenn temporäre Objekte erstellt werden, auf die Sie keinen Zugriff haben, sind sie im Allgemeinen ein guter Kandidat für 'move semantics'. – sameerkn

Antwort

2

In den meisten Fällen gibt es keinen großen Unterschied zwischen Kopieren und Verschieben. Es ist nur interessant, wenn Sie etwas besitzen, das Sie nicht vervielfältigen wollen. Wie ein Socket oder Speicher, der dem Objekt zugewiesen ist. Es ist also nur interessant, wenn etwas teuer ist (z. B. einen großen Teil des Speichers kopieren, wenn Sie nur einen benötigen) und Sie müssen sich um den Besitz kümmern (keine zwei Zeiger auf den gleichen Speicher oder einen Socket usw. zeigen). .).

In beiden Beispielen ist es am wahrscheinlichsten, dass der Compiler eine RVO-Rückgabewert-Optimierung durchführt, die das Kopieren oder Verschieben überflüssig macht. Vector definiert move, so dass der Compiler die move-Semantik wann immer es kann (rvalue-Semantik) verwendet, und Sie können es mit std :: move erzwingen. Aber neigher deiner Beispiele wird deswegen schneller sein. Read more about move.

Wenn Sie neugierig sind, können Sie sowohl kopieren und verschieben und schreiben von ihnen auf die Konsole.

Greeting(const Greeting& g) 
{ 
    std::cout << "Copy"; 
    // Copy it 
} 

Greeting(Greeting&& g) 
{ 
    std::cout << "Move"; 
    // Move it 
} 

Normalerweise ist das was passiert.

Greeting foo(){ Greeing a; return a; } 
Greeting a; // Normal construction 
Greeting b(a); // Copy of 'a' 
Greeting c(std::move(a)); // Move, 'a' will be changed 
Greeting d(foo()); // Move from rvalue which is returned from foo() unless RVO kicks in