Move-Konstruktor



  • Kann man das nicht dem Compiler überlassen? Der kennt doch den Datentyp und ich habe schon Gerüchte gehört, dass der Compiler automatisch die optimale Kopiermethode auswählt.
    Man könnte im Compiler Explorer mal sehen, welchen Code welcher Compiler erzeugt.



  • @Quiche-Lorraine sagte in Move-Konstruktor:

    Ich würde trotzdem vor dem memcpy folgendes einfügen:

    Dann lieber so

    MeasureArr::MeasureArr (const MeasureArr& msAr) : msPtr(new Measure[msAr.max]), max(msAr.max), anz(msAr.anz)  {
    	std::cout << "Kopierkonstruktor\n";
    	std::copy_n (msAr.msPtr, anz, msPtr);
    }
    


  • Vielen Dank...damit kommt mit Sicherheit so schnell keine Langeweile auf :D.
    Welche Frage sich jetzt noch ergeben hat:
    Warum wird in der Funktion append() den dynamischen Element msPtr[] eigentlich nicht mit new das Objekt rd zugewiesen,
    so wie es auch im Konstruktor gemacht wurde? (msPtr[] = new rd) Danke!



  • Vergleiche mal beide Datentypen bzw. schau dir mal deinen eigenen Kopierkonstruktor oder operator = an...



  • @C-Sepp sagte in Move-Konstruktor:

    Warum wird in der Funktion append() den dynamischen Element msPtr[] eigentlich nicht mit new das Objekt rd zugewiesen, so wie es auch im Konstruktor gemacht wurde? (msPtr[] = new rd) Danke!

    Nein, aus gutem Grund hatte ich den Konstruktor verändert.

    MeasureArr(const size_t mx) : msPtr(new Measure[mx]), max(mx), anz(0) {}
    

    Es wird hier dem Pointer msPtr der Wert aus der Allokation new Measure[mx] zugewiesen. Es wird hier keinerlei Objekt des Typs Measure zugewiesen, sondern nur Speicher für die Anzahl mx an Measure Objekte angefordert. Später kann man dann mit append Measure Objekte in dem bereits allozierten Speicher ablegen.



  • @john-0 sagte in Move-Konstruktor:

    Es wird hier keinerlei Objekt des Typs Measure zugewiesen, sondern nur Speicher für die Anzahl mx an Measure Objekte angefordert.

    Wie kommst du darauf?
    Es wird hier ein Array erzeugt und für jedes Array-Element dessen Standardkonstruktor (hier also Measure()) aufgerufen.

    PS: In deinem Code in Zeile 23 fehlen Kommentarzeichen.



  • Wusst ich's doch. Analog zu string*pStr = new string(20,'X'); könnte man nämlich auch
    msPtr = new Measure(1, 2); in der Funktion schreiben. Jetzt stellt sich nur noch die Frage
    warum bei msPtr[1] = new Measure(1, 2); immer eine Fehlermeldung kommt?



  • Welchen Datentyp hat msPtr und welchen msPtr[i]?

    Außerdem mußt du zwischen statischem und dynamischen Datentyp (zur Laufzeit) unterscheiden.



  • @Th69 sagte in Move-Konstruktor:

    Wie kommst du darauf?

    In append wird ein Wert als Parameter übergeben im Konstruktor nicht.



  • Ah stimmt...msPtr ist ja vom Typ Zeiger auf Measure, msPtr[i] spricht wiederrum den Wert an auf den msPtr[i] zeigt.



  • Wie bereits erwähnt, wird mit msPtr[i] = rd ja ein Wert an msPtr übergeben. Welcher Wert ist das denn...eigentlich wird doch ein Objekt als Parameter übergeben? Wenn das der Wert des Membervariablen des üergebenen Objektes ist, wie verhält sich das dann für mehrere Membervariablen? Danke!



  • @C-Sepp sagte in Move-Konstruktor:

    Ah stimmt...msPtr ist ja vom Typ Zeiger auf Measure, msPtr[i] spricht wiederrum den Wert an auf den msPtr[i] zeigt.

    Der erste Teilsatz stimmt, der zweite nicht:
    msPtr[i] zeigt nicht auf irgendetwas, sondern es beinhaltet ein Measure-Objekt!

    Also wird bei msPtr[i] = rd einfach das Measure-Objekt rd an den Index i des Arrays msPtr kopiert (bedenke, daß msPtr[i] <=> *(msPtr+i)).



  • Warum eine Zeigervariable jetzt ein Objekt beinhalten soll/kann ist mir nicht klar. Eigentlich verweist ein/dieser Zeiger
    doch auf einen Speicherbereich/Array von Objekten vom Typ Measure.
    Jetzt ist mir auch wieder nicht klar, warum man msPtr[i] = new Measure(1,2) nicht schreiben kann?
    msPtr und msPtr[i] sind doch beide vom Typ Zeiger auf Measure, wobei ich mich mit msPtr[i]/ *(msPtr+i) in der Werteebene bewege bzw. mit msPtr der Zeigervariablen einen bestimmten Speicherbereich zuweisen kann.



  • @C-Sepp sagte in Move-Konstruktor:

    msPtr und msPtr[i] sind doch beide vom Typ Zeiger auf Measure,

    Nein, ich habe meinen ursprünglichen Code korrigiert und im Konstruktor einen Aufruf eingebaut, der die Namen der Typen ausgibt. Falls man g++ nutzt werden die Namen in lesbarer Form ausgegeben, bei anderen Compiler hängt es von deren Vorgaben gab.

    P.S. Die Forensoftware missinterpretiert .cc als Toplevel Domain.



  • Könnt ihr mir verraten, welche Datentypen msPtr und msPtr[i] haben? Demangle.h ließ sich bei mir nicht inkludieren.
    Komischerweiser kann man msPtr[1] auch 2/3 Werte ohne Fehler zuweisen (msPtr= (1, 2, 3). Und das obwohl der
    Konstruktor für Measure doch nur über ein Argument verfügt??? Nochmals vielen Dank!



  • @C-Sepp sagte in Move-Konstruktor:

    Könnt ihr mir verraten, welche Datentypen msPtr und msPtr[i] haben?

    Du hast doch in deinem Programm Measure* msPtr; stehen. Also ist msPtr ein Zeiger auf Measure und msPtr[i] ein Measure.

    Komischerweiser kann man msPtr[1] auch 2/3 Werte ohne Fehler zuweisen (msPtr= (1, 2, 3).

    Hier verstehe ich schon die Frage nicht. Wieso zwei Drittel? Oder zwei von drei? Ergibt für micht beides keinen Sinn hier. Und das hier msPtr= (1, 2, 3) ist rechts ein Ausdruck mit dem Komma-Operator. Der ergibt 3. Und der kann wohl kaum einem Pointer zugewiesen werden.



  • @C-Sepp sagte in Move-Konstruktor:

    Könnt ihr mir verraten, welche Datentypen msPtr und msPtr[i] haben? Demangle.h ließ sich bei mir nicht inkludieren.

    Die Ausgabe meines Programms

    Konstruktor
    type of msPtr    Measure*
    type of msPtr[i] Measure
    Konstruktor
    type of msPtr    Measure*
    type of msPtr[i] Measure
    Kopierkonstruktor
    Move-Zuweisung
    Destruktor
    Destruktor
    Destruktor
    


  • @john-0 Alles klar!
    @wob : Ich meinte mit "2/3" "2 bzw. 3". In den Codescnipsel ist ein kleiner Fehler...soory! Ich meinte msPtr[i]= (1,2,3) anstatt msPtr = (1,2,3)



  • Das sind die Tücken der C++ Programmierung: wie @wob schon geschrieben hat, wird mittels (1,2,3) der Komma-Operator benutzt (nicht das Parametertrennzeichen(!), da ja kein Funktionsname vorher steht) und dann wird (da der Konstruktor für Measure nicht explicit ist), der Measure-Konstruktor mit dem letzten Wert der Komma-Liste (d.h. hier 3) aufgerufen.



  • Top...vielen Dank!


Anmelden zum Antworten