2016-06-01 10 views
2

dereferencing habe ich den folgenden Code (http://coliru.stacked-crooked.com/a/a0e5ff6ee73634ee):Verschieben Semantik und Konstrukteuren, wenn ein neues

#include <iostream  

class A { 
    public: 
    explicit A(int a)   {std::cout << "Main constructor" << std::endl;} 
    A(const A& a)    {std::cout << "Copy constructor" << std::endl;} 
    A& operator =(const A& a) {std::cout << "Copy assignment" << std::endl; return *this;} 
    A(A&& a)     {std::cout << "Move constructor" << std::endl;} 
    A& operator =(A&& a)  {std::cout << "Move assignemnt" << std::endl; return *this;} 
}; 

int main(void) { 
    std::cout << "\nA a3(A(0))" << std::endl; 
    A a3(A(0)); 
    std::cout << "\nA a31(std::move(A(0)))" << std::endl; 
    A a31(std::move(A(0))); 
    std::cout << "\nA a4(*(new A(0)))" << std::endl; 
    A a4(*(new A(0))); 
    std::cout << "\nA a41(std::move(*(new A(0))))" << std::endl; 
    A a41(std::move(*(new A(0)))); 
} 

Dieser Code schreibt folgendes:

A a3(A(0)) 
Main constructor 

-> Nach dem Lesen Move semantics and copy constructor Ich gehe davon aus RVO passiert und a3 übernimmt den Inhalt der Konstruktion von A (0).

A a31(std::move(A(0))) 
Main constructor 
Move constructor 

-> OK

A a4(*(new A(0))) 
Main constructor 
Copy constructor  

-> Warum ist das nicht ein Schritt Konstruktor anstelle der Copy-Konstruktor?

A a41(std::move(*(new A(0)))) 
Main constructor 
Move constructor 

-> OK
EDIT: Nach der Analyse des Problems ein wenig tiefer erkannte ich, dass tatsächlich @sameerkn richtig ist. Wie @Angew vorgeschlagen hat, habe ich versucht zu analysieren, was mit einer statischen Variable passiert: Solche Variablen werden nicht so bewegt, wie man es erwarten könnte (sie scheinen als konstante Variablen behandelt zu werden). finden Sie hier Code: http://melpon.org/wandbox/permlink/RCntHB9dcefv93ID

Code Folgende:

A a1(testStatic(1)); 
A a2(std::move(*(a1.getPointer()))); <-- Moving a dereference 
std::cout << "\na1.mValue = " << a1.mValue << std::endl; 
std::cout << "a2.mValue = " << a2.mValue << std::endl; 

Wir kommen wieder:

Main constructor: This is my long String that should not be SSOed [STATIC] 
Copy constructor: This is my long String that should not be SSOed [STATIC] 
return aLocal 
Move constructor <-- The dereferenced pointer is moved as expected 
Destructor: [mValue moved away] <-- See here that the string was moved away 
Move constructor <-- Moved again because of std::move 

Antwort

1
new A(0); 

Erstellen eines Objekts über "neu". (ANMERKUNG: Es erzeugt ein reines Objekt mit einer Identität, die durch die Adresse identifiziert werden kann, die von "neu" im Code zurückgegeben wird, und dieses Objekt steht dem Code für seine Verwendung zur Verfügung und in keiner Weise als temporäres namenloses Objekt.)

Und semantische Arbeit auf rein temporäres Objekt verschieben, dessen Identität nicht zur Verfügung steht.

+0

Hallo @sameerkn, vielen Dank für Ihren Kommentar.Tatsächlich gibt new einen rohen Zeiger zurück, und solch ein Zeiger ist ein POD-Typ (http://en.cppreference.com/w/cpp/concept/PODType) und daher nicht bewegbar. In den Fragen habe ich mich gefragt, warum die Dereferenzierung dieses Zeigers nicht verschoben wurde. – JeanPhi

+1

Ich denke, zu den Bedingungen, die: '" nicht Beweglich "bedeutet" mit bestimmten Bereich (Adresse) im Adressraum, der bekannt/identifizierbar ist und verwendet werden kann. " "Beweglich" bedeutet "Temporärer Platz/Adresse, die während der Laufzeit nicht identifizierbar ist oder temporäre Objekte, auf die an keiner anderen Stelle im Programm Bezug genommen werden kann". Mit new erstellte Objekte sind nicht temporär. – sameerkn

+0

Hallo @sameerkn, danke für deine Erklärung eigentlich wie ich im edit geschrieben habe ist deine Erklärung die richtige. – JeanPhi

7
A a4(*(new A(0))) 
Main constructor 
Copy constructor  

-> Warum ist das nicht ein Schritt Konstruktor anstelle der Kopie Konstrukteur ?

Da die Dereferenzierung eines Zeigers eine Lvalue-Referenz ergibt. Die Tatsache, dass der Zeiger selbst ein rvalue ist spielt keine Rolle — und warum sollte es? Sie können sehr leicht einen rvalue-Zeiger auf etwas zeigen, das definitiv kein rvalue ist. Beispiel:

std::string s{"42"}; 

std::string* getPointer() 
{ 
    return &s; 
} 

int main() 
{ 
    std::string x(*getPointer()); 
    std::cout << s; 
} 

Der Zeiger zurückgegeben durch getPointer ist ein R-Wert, genauso wie der Zeiger um new A zurückgegeben. Aber Sie würden sicherlich nicht erwarten, dass der Code den Inhalt von s in x verschieben, würden Sie?

+0

Hi @Angew, ich habe die Auflösung auf sameerkn wie vom EDIT verschoben ich habe geschrieben es ist eigentlich möglich eine dereferenzierte Funktion aber nicht eine neue zu verschieben. Ihr Punkt mit statischen war sehr interessant. Ich fügte einen Link zu einem Codeausschnitt hinzu, der zeigt, dass statische Variablen tatsächlich nicht beweglich sind (was ich erwartet hatte, aber nie gelesen habe). – JeanPhi

Verwandte Themen