Wieder der Copy-Konstruktor
-
Moment mal, das heisst es ist zwingend dass alle Objekte die durch den Copycon erzeugt werden eine Ref auf das ursprungsobjekt ist?
-
eh nun verwirrst du mich etwas.
also ein CopyCon kopiert das übergebene objekt und man hat am ende dann zwei objekte. das zu kopierende und einmal die kopie.
sie sind damit von einander unabhängig und wenn du das eine löschst ist das andere noch vorhanden.
-
Im CTor sitzt Du im inneren des Kopiergerätest und das übergebene Objekt ist das Baltt , welches oben auf der Glasblatte liegt und kopiert werden möchte

-
class A{ public: A(): i( new int(1)); ~A(); setI( int in){ *i = in; } private: int *i; }; A::~A(){ delete i; } // so könnte dann der copyconst vom compiler genereiert aussehen A::A( const A& src){ i = src.i; //kopiert also den zeiger //this.i und src.i zeigen also nun auf den gleichen //speicherbereiche ( flache kopie ) } /////////////////////////// //mit geschriebenem copyconst class B{ public: B():i( new int(1)); ~B(); B(const B& src ); setI( int in){ *i = in; } private: int *i; }; B::~B(){ delte i; } B::B(const B& src){ if( this != &src ){ //überprüfen ob zuweisung an sich selbst i = new Int(1); //neuen speicher alloziieren *i = *(src.i); //kopiere den wert //src.i und this.i zeigen auf unterschiedlichen speicher //tiefe kopie } }das wäre dann nen prog:
int main{ A* a1 = new A(); a1->setI(234); A *a2( a1 ); a2->setI( 9876 ); // nun ist auch *(a1.i) == 9876 delete a1; a2->setI( 21 ); // error der pointer von i zeigt nämlich nun in nicht //alloziierten speicher, der wurde nämlich mit dem zerstören von a1 wieder //freigegeben B * b1 = new B(); b1->setI( 45 ); B *b2 = new B(b1); b2->setI( 565 ); // *(b1.i) ist immer noch 45 delete b1; b2->setI(45677); //geht ohne weiteres. der pointer ist immer noch ok, da er auf //seinen eigenen speicherbereiche zeigt return 0; }so ich hoffe das hilft
-
aso ja stimmt sry, trotzdem wieso funzt hier kein normales call by value??
EDIT: is keine antwort auf vorposter hab gar nur zu spät gepostet-
-
wenn ich mich nicht täusche MUSS der CopyConst diese Signatur haben.
Klasse::Klasse( const Klasse& src){}
dabei ist src natürlich nur ein bezeichner und kann auch anders lauten
wäre es nämlich keine reference sondern ein call by value würdest du das objekt erstmal beim übergeben kopieren und dann nochmals innerhalb deines kopierkonstruktors.
nun stelle dir mal eine super komplexe klasse vor die mehr als 10000 andere objekt enthält die wiederum etwas komplexer sind.
und nun male dir mal aus weöche performance auswirkungen es hätte jedesmal alle objekte 2 mal zu kopieren...
-
ConfusedGuy schrieb:
wenn ich mich nicht täusche MUSS der CopyConst diese Signatur haben.
Klasse::Klasse( const Klasse& src){}
Du täuschst dich. Korrekt ist, dass der Copy-Ctor einen Referenz-Parameter erhalten muss. Dabei ist aber egal, ob das Ziel der Referenz als const, volatile, const volatile oder nichts von alledem angesehen werden soll.
wäre es nämlich keine reference sondern ein call by value würdest du das objekt erstmal beim übergeben kopieren und dann nochmals innerhalb deines kopierkonstruktors.
[...]
und nun male dir mal aus weöche performance auswirkungen es hätte jedesmal alle objekte 2 mal zu kopieren...Es käme noch viel schlimmer, da du nicht zweimal sondern bis in alle Ewigkeit kopieren würdest. Beim "by value"-Aufruf wird eine Kopie erzeugt. Für das Erzeugen einer Kopie wird der Copy-Ctor verwendet. Würde der Copy-Ctor seinen Parameter "by value" übernehmen, müsste beim Aufruf des Copy-Ctors erstmal wieder eine Kopie erzeugt werden. Das würde wieder den Copy-Ctor aufrufen, wobei wieder eine Kopie erzeugt werden müsset, was wieder den Copy-Ctor aufrufen würde... und so weiter ...
-
ah gut, dann habe ich ja auch noch was gelernt

danke
-
und ich auch. danke.

-
HumeSikkins schrieb:
...
Es käme noch viel schlimmer, da du nicht zweimal sondern bis in alle Ewigkeit kopieren würdest....Schön, habe ich also recht vermutet. (Habe ich aber noch nirgendwo gelesen ... sollte man vielleicht mal aufschreiben).
Gruß,
Simon2.
-
-
HumeSikkins schrieb:
@Simon2
Ist ja letztlich irrelevant, da eine Signatur wie:Foo(Foo f);schlicht nicht erlaubt ist.
Aber ich finde es immer besser, wenn ich einen konkreten Grund sehe, warum etwas nicht erlaubt ist. Kann ich mir einfach leichter merken, wenn es plausibel ist.
Gruß,
Simon2.