[gelöst] Move, Copy und c'tor - Reihenfolge



  • Hallo,

    ich arbeite mit Visual Studio 2012.

    Folgender Code

    class A
    {
    public:
      A();
      A(const A& ToCopy);
      A(A&& ToMove);
      operator=(const A& ToCopy) { Set(ToCopy);            };
      operator=(A&& ToMove)      { Set(std::move(ToMove)); };
      void Set(const A& ToCopy);
      void Set(A&& ToMove);
    };
    
    A Eins, Zwei, Drei;
    
    Eins = std::move(Zwei);    // Vorgang eins
    Eins.Set(std::move(Drei)); // Vorgang zwei
    

    Ich habe das mit dem Mover so verstanden, dass jetzt eigentlich Vorgang Eins und Zwei beide (einmal über Hilfsweg) in die Set(A&&) laufen müssten. Passiert aber nicht.

    Vorgang zwei macht meine Set-Funktion, da explizit aufgerufen wurde.
    Vorgang eins macht aber den c'tor A(A&&):

    // Vorgang eins wie es gemacht wird (Symbolisch)
    A tmp(Drei);
    &Eins = &tmp;
    

    Ich wollte aber

    // Vorgang eins Wunschdenken (Symbolisch)
    Eins.operator=(std::move(Drei));
    

    Ich hab das mit dem Debugger mehrfach getestet. Wo liegt mein Gedankenfehler?
    Mir geht es um keinen speziellen Fall. Ich übe einfach gerade die Umstellung auf C++11.



  • stefanjann schrieb:

    ich arbeite mit Visual Studio 2012.

    Warum mit so einem veralteten Compiler?

    Schön, dass du deinen Code vollständig eingefügt hast, so kann man es ganz einfach nachvollziehen.

    #include <iostream>
    
    int main()
    {
    class A
    {
    public:
      A(){}
      A(const A& ToCopy){}
      A(A&& ToMove){}
      A& operator=(const A& ToCopy) { Set(ToCopy); return *this;            }
      A& operator=(A&& ToMove)      { Set(std::move(ToMove));  return *this;}
      void Set(const A& ToCopy){ std::cerr << "Set(const A& ToCopy)\n";}
      void Set(A&& ToMove){ std::cerr << "Set(A&& ToMove)\n"; }
    };
    
    A Eins, Zwei, Drei;
    
    Eins = std::move(Zwei);    // Vorgang eins
    Eins.Set(std::move(Drei)); // Vorgang zwei
    }
    

    mit VS2013 gibt:

    Set(A&& ToMove)
    Set(A&& ToMove)

    was wohl deinen Erwartungen entspricht.



  • manni66 schrieb:

    stefanjann schrieb:

    ich arbeite mit Visual Studio 2012.

    Warum mit so einem veralteten Compiler?

    Weil die Firma derzeit noch mit TFS 2012 arbeitet. Ist nicht so schnell zu machen alles auf 2013 umzustellen. Wird aber Anfang Januar in Angriff genommen. Das ist ja meine Arbeit momentan alles vorzubereiten und den Umstieg von unseren C++98 auf C++11 zu organisieren und zu planen. Sind halt schon sehr viele "alte" Programmierungen und Libs die portiert werden müssen.

    manni66 schrieb:

    Schön, dass du deinen Code vollständig eingefügt hast, so kann man es ganz einfach nachvollziehen.

    Mein Code ist derzeit über 6 Klassen in Kombination mit einigen Templates verteilt und ein bisschen rumgeerbt wird auch noch. Ich dachte, ich fasse das Grundproblem zusammen, damit man hier nicht unnötig 500 Zeilen Code lesen muss.

    manni66 schrieb:

    mit VS2013 gibt:

    Set(A&& ToMove)
    Set(A&& ToMove)

    was wohl deinen Erwartungen entspricht.

    Ja, das wären meine Erwartungen. Aber kann es "nur" an der VS-Version liegen? Oder kann das noch von z.B. Vererbungen, Templates oder anderen Dingen mit beeinflusst werden? Kann man das generell beantworten? Ich meine so typische "Einsteiger-Unwissenheit" bei std::move?


  • Mod

    stefanjann schrieb:

    manni66 schrieb:

    Schön, dass du deinen Code vollständig eingefügt hast, so kann man es ganz einfach nachvollziehen.

    Mein Code ist derzeit über 6 Klassen in Kombination mit einigen Templates verteilt und ein bisschen rumgeerbt wird auch noch. Ich dachte, ich fasse das Grundproblem zusammen, damit man hier nicht unnötig 500 Zeilen Code lesen muss.

    Das ist auch gut und richtig so, aber optimalerweise solltest du ein ausführbares (oder bis auf den relevanten Fehler ausführbar) Beispiel präsentieren. Die paar Zeilen, die manni66 ergänzt hat, machen da schon den Unterschied.
    Siehe:
    http://www.c-plusplus.net/forum/304133



  • stefanjann schrieb:

    manni66 schrieb:

    Schön, dass du deinen Code vollständig eingefügt hast, so kann man es ganz einfach nachvollziehen.

    Mein Code ist derzeit über 6 Klassen in Kombination mit einigen Templates verteilt und ein bisschen rumgeerbt wird auch noch. Ich dachte, ich fasse das Grundproblem zusammen, damit man hier nicht unnötig 500 Zeilen Code lesen muss.

    Dein Beispiel ist nicht übersetzbar. Wenn man es übersetzbar macht, funktioniert es. Hättest du eine übersetzbare Version zusammengestellt, hättest du selber erkannt, dass dein Problem woanders liegt!

    stefanjann schrieb:

    Ja, das wären meine Erwartungen. Aber kann es "nur" an der VS-Version liegen?

    Nein, VS2012 liefert das gleiche Ergebnis, was du mit meinem vollständigen Beispiel leicht selber feststellen könntest.



  • Hallo,

    danke für die Hinweise. Ich werde zukünftig keinen Psycho...äh...Pseudo-Code mehr posten, sondern lauffähiges C++.

    Ja ihr habt Recht, hätte ich den Code den ich hier geschrieben habe einmal lauffähig durchgetestet hätte ich schon gesehen, dass es doch das tut, was es soll.

    Ich hab meinen Debugger auch noch extrem gequält und festgestellt, dass mit ein fehlendes "explizit" einen cast und somit einen c'tor bescherrt hat. Aber wie das manchmal so ist mit 25fachen Vererbungen über 16 Templates...sowas sucht man recht lange. Noch dazu, weil es sich gerade um Klassen handelt die irgendwann im Jahre 200 v. Chr. von irgendeinem ehemaligen Mitarbeiter erstellt wurden.

    Peinlich, Sorry. Gelobe Besserung.
    Fehler gefunden und behoben und nun "moved" es wieder richtig.

    Danke an alle.
    Stefan


Anmelden zum Antworten