Funktionen mit RValue Referenzen als Parameter
-
@asd1 sagte in Funktionen mit RValue Referenzen als Parameter:
So ganz werde ich da nicht schlau.
Ersetzte deine main Funktion durch
int main() { MoveClass m1; m1.setArray(); m1.print(); std::cout<<std::endl; aufrufReferenz(m1); aufrufValue(m1); aufrufRValueReferenz(std::move(m1)); // Reihenfolge! Nach dem move ist p == nullptr! m1.print(); std::cout << "======\n"; MoveClass m2; aufrufValue(std::move(m2)); // Hier wird nicht kopiert! m2.print(); }
ersetze aufrufRValueReferenz durch
void aufrufRValueReferenz(MoveClass&& moved) // hier wird kein neues Objekt erzeugt { MoveClass m( std::move(moved)); // erst hier ist der "move" komplett std::cout <<"Print in aufrufRValueReferenz"<<std::endl; m.print(); std::cout <<"Print Ende in aufrufRValueReferenz"<<std::endl<<std::endl; }
Vielleicht helfen die Kommentare weiter
-
@asd1 sagte in Funktionen mit RValue Referenzen als Parameter:
//Destructor ~MoveClass() { std::cout <<"Destructor"<<std::endl; delete[] p; p= nullptr; }
OT:
p= nullptr;
ist völlig überflüssig. p ist nach}
nicht mehr da!
-
@manni66 sagte in Funktionen mit RValue Referenzen als Parameter:
@asd1 sagte in Funktionen mit RValue Referenzen als Parameter:
Was meinst Du mit SIZE? Habe SIZE mit ARRAYSIZE ersetzt.
Ich hatte angenommen, dass der Konstruktor mit int Parameter ein Array mit anderer Größe anlegen sollte.
Nö, bezieht sich auf b.
-
@manni66 sagte in Funktionen mit RValue Referenzen als Parameter:
@asd1 sagte in Funktionen mit RValue Referenzen als Parameter:
//Destructor ~MoveClass() { std::cout <<"Destructor"<<std::endl; delete[] p; p= nullptr; }
OT:
p= nullptr;
ist völlig überflüssig. p ist nach}
nicht mehr da!Stimmt.
-
@manni66 sagte in Funktionen mit RValue Referenzen als Parameter:
@asd1 sagte in Funktionen mit RValue Referenzen als Parameter:
So ganz werde ich da nicht schlau.
Ersetzte deine main Funktion durch
int main() { MoveClass m1; m1.setArray(); m1.print(); std::cout<<std::endl; aufrufReferenz(m1); aufrufValue(m1); aufrufRValueReferenz(std::move(m1)); // Reihenfolge! Nach dem move ist p == nullptr! m1.print(); std::cout << "======\n"; MoveClass m2; aufrufValue(std::move(m2)); // Hier wird nicht kopiert! m2.print(); }
ersetze aufrufRValueReferenz durch
void aufrufRValueReferenz(MoveClass&& moved) // hier wird kein neues Objekt erzeugt { MoveClass m( std::move(moved)); // erst hier ist der "move" komplett std::cout <<"Print in aufrufRValueReferenz"<<std::endl; m.print(); std::cout <<"Print Ende in aufrufRValueReferenz"<<std::endl<<std::endl; }
Vielleicht helfen die Kommentare weiter
Danke! Ich werde mir das gleich in Ruhe anschauen.
-
OK. Danke.
Dann hätte ich eine weitere Frage.// Aufruf über Referenz void aufrufReferenz(MoveClass& moved) { MoveClass m( std::move(moved)); //Neu hinzugkommen std::cout <<"Print in aufrufReferenz"<<std::endl; moved.print(); std::cout <<"Print Ende in aufrufReferenz"<<std::endl; }
Hätte doch denselben Effekt mit aufrufReferenz(m1)? Einzige Unterschied wäre, dass man nur LValue Referenzen angeben darf. aufrufReferenz(Moveclass(4)) wäre zum Beispiel nicht möglich.
-
@manni66 sagte in Funktionen mit RValue Referenzen als Parameter:
@asd1 sagte in Funktionen mit RValue Referenzen als Parameter:
So ganz werde ich da nicht schlau.
Ersetzte deine main Funktion durch
int main() { MoveClass m1; m1.setArray(); m1.print(); std::cout<<std::endl; aufrufReferenz(m1); aufrufValue(m1); aufrufRValueReferenz(std::move(m1)); // Reihenfolge! Nach dem move ist p == nullptr! m1.print(); std::cout << "======\n"; MoveClass m2; aufrufValue(std::move(m2)); // Hier wird nicht kopiert! m2.print(); }
ersetze aufrufRValueReferenz durch
void aufrufRValueReferenz(MoveClass&& moved) // hier wird kein neues Objekt erzeugt { MoveClass m( std::move(moved)); // erst hier ist der "move" komplett std::cout <<"Print in aufrufRValueReferenz"<<std::endl; m.print(); std::cout <<"Print Ende in aufrufRValueReferenz"<<std::endl<<std::endl; }
Vielleicht helfen die Kommentare weiter
Wenn ich richtig verstanden habe, ist der Sinn für
void aufrufRValueReferenz(MoveClass&& moved)
den Move-Konstruktor bzw. Move Assignment in der Funktion einzusetzen. Ist das richtig?
-
@asd1 sagte in Funktionen mit RValue Referenzen als Parameter:
// Copy constructor MoveClass(const MoveClass &other):b{other.b} { std::cout <<"Copy constructor"<<std::endl; p=new int[ARRAYSIZE]; for (int i=0; i<ARRAYSIZE; i++) { p[i]=other.p[i]; } } // ... MoveClass& operator=(const MoveClass &other) { std::cout <<"Assignment operator"<<std::endl; b=other.b; delete[] p; p=new int[ARRAYSIZE]; for (int i=0; i<ARRAYSIZE; i++) { p[i]=other.p[i]; } return *this; }
Fällt dir auf daß da was doppelt ist? Ist auch nicht exception-safe. Google mal nach dem Copy and Swap Idiom.
-
@asd1 sagte in Funktionen mit RValue Referenzen als Parameter:
Hätte doch denselben Effekt mit aufrufReferenz(m1)?
Ja. Man sieht dem Funktionsaufruf aber nicht an, dass das Objekt danach nicht mehr zu gebrauchen ist.
-
@asd1 sagte in Funktionen mit RValue Referenzen als Parameter:
den Move-Konstruktor bzw. Move Assignment in der Funktion einzusetzen. Ist das richtig?
Man kann auch eine andere Funktion aufrufen, die die Referenz annimmt.