Kopierinitialisierung



  • Da ich es immer noch nicht gaz verstehe: was passiert bei einer Kopierinitialisierung oder wann findet diese genau statt?

    Wenn ich eine Klasse Car habe, in der Konstruktor, Kopierkonstruktor und Zuweisungsoperator selbst definiert sind, was passiert dann in diesen Fällen?

    Car x();   // Einfach der Konstruktor?
    Car y(x);  // Kopierkonstruktor?
    Car z = y; // Kopierkonstruktor?
    z = x;     // Zuweisung?
    

    Gibt es irgendetwas zu beachten ?



  • Car x; // Default constructor
    Car y(x); // Copy constructor
    Car z = x; // Copy constructor
    z = y; // Assign operator
    
    Car x (); // Function declaration
    Car x (5); // Constructor call
    

    BTW: Einfach eine kleine Klasse bauen die in den einzelnen Konstruktoren/Operatoren immer via cout eine Meldung ausgibt.

    MfG SideWinder



  • Und immer brav die Regel Der-Großen-Drei beachten...



  • Kóyaánasqatsi schrieb:

    Und immer brav die Regel Der-Großen-Drei beachten...

    ...und generell sich mit allen Beiträgen hier: http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs beschäftigen.

    MfG SideWinder



  • Frage:

    Car z = x; // Copy constructor
    

    Ist es wirklich sicher (standard !) das in diesem Fall der Copy-Constructor aufgerufen wird, und nicht zuerst der Default-Contructor mit anschließender Zuweisung ??



  • Chew-Z schrieb:

    Ist es wirklich sicher (standard !) das in diesem Fall der Copy-Constructor aufgerufen wird, und nicht zuerst der Default-Contructor mit anschließender Zuweisung ??

    Ja, sofern die Typen gleich sind und es sich bei x nicht um ein temporäres Objekt handelt.

    Falls z und x unterschiedliche Typen haben, darf entweder der Konvertierungskonstruktor und dann der Kopierkonstruktor aufgerufen werden (1) oder direkt der Konvertierungskonstruktor (2).

    Car tmp(x); // (1) Konvertierungskonstruktor
    Car z(tmp); //     Kopierkonstruktor
    
    Car z(x);   // (2) Konvertierungskonstruktor
    

    Wenn hingegen x ein temporäres Objekt ist (beispielsweise ein Rückgabewert einer Funktion), darf z direkt initialisiert werden, ohne dass ein Kopierkonstruktor aufgerufen wird. Die Kopie wird also wegoptimiert.

    Standardkonstruktor und Zuweisungsoperator werden in diesem Kontext aber nie aufgerufen. Daher müssen sie auch nicht öffentlich zugreifbar sein.



  • Das dies Sinn macht sehe ich ein. Aber ist dies eine Eigenschaft (heutiger) Compiler oder ist dieses durch den Standard so vorgegeben ??


  • Mod

    Chew-Z schrieb:

    Das dies Sinn macht sehe ich ein. Aber ist dies eine Eigenschaft (heutiger) Compiler oder ist dieses durch den Standard so vorgegeben ??

    C++ Standard 8.5.11 schrieb:

    The form of initialization (using parentheses or 🙂 is generally insignificant, but does matter when the entity being initialized has a class type; see below. A parenthesized initializer can be a list of expressions only when the entity being initialized has a class type.



  • Chew-Z schrieb:

    Das dies Sinn macht sehe ich ein. Aber ist dies eine Eigenschaft (heutiger) Compiler oder ist dieses durch den Standard so vorgegeben ??

    Der Standard macht Vorgaben. Gewisse davon sind "implementation-defined", also den Compilerherstellern überlassen. Zum Beispiel betrifft das die oben erwähnten Varianten (1) und (2).


Anmelden zum Antworten