1 zu 1 Kopie einer Klasse
-
Ich vermute mal: Falsches Forum.
Falls doch C++/CLI: http://www.c-plusplus.net/forum/viewtopic-var-t-is-248502.html
-
mogel
13:51:45 17.09.2009 Titel: Zitieren
Moin,in dem Du einen Copy-Konstruktor schreibst und darin die einzelnen Member umkopierst
hand, mogel
@morgel: Das ist bislang die einzige Möglichkeit die mir auch eingefallen ist, könnte aber recht aufwendig werden und würde am liebsten den Weg mit dem geringsten Widerstand gehen.
witte
13:53:49 17.09.2009 Titel: Zitieren
Du solltest erstmal sagen ob nach der deep copy beide Objekte auf dieselben Member-Exemplare verweisen sollen oder ob diese auch mitkopiert werden müssen. Also wenn in einem Objekt der Member verändert wird ob dieses auch im anderen sichtbar sein soll.@witte: Es soll alles mitkopiert werden. Also ohne Verweise
theta
14:04:00 17.09.2009 Titel: Zitieren
Ich vermute mal: Falsches Forum.
Falls doch C++/CLI: http://www.c-plusplus.net/forum/viewtopic-var-t-is-248502.html@theta : Ja falsches Forum. Hab mich verklickt, weiss aber auch nicht wie ich den Beitrag verschiebe. Sollte natrürlich in das C++ Forum.
-
chewbo schrieb:
Das ist bislang die einzige Möglichkeit die mir auch eingefallen ist, könnte aber recht aufwendig werden und würde am liebsten den Weg mit dem geringsten Widerstand gehen.
dann wirst Du Dich weiter auf eine weite Reise begeben müssen anstatt es selbst zu machen ... und denke daran, Effizienz - mein junger Padawn - Effizienz und nicht Faulheit wird Dich zum Ziel führen
-
Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum C++/CLI mit .NET in das Forum C++ verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
wo liegt das problem? also was verstehst du nicht?
struct T { /*...*/ }; struct X { private: T* m; public: X(const X &other) : m(0) { try { m = new T(other.m); } catch(...) { delete m; throw; } } };eigtl würde
X(const X &other) { m = new T(other.m); }reichen, allerdings können hier an 2 Stellen Exceptions fliegen: Beim Speicher anfordern und im Copy-CTor von T. Also könnte es sein, dass der Speicher (erfolgreich) angefordert wurde und dann ne Exception fliegt und du ein Speicherleck hast, da für nicht fertig erstellte Objekte kein Destruktor erstellt wird und somit auch kein evtl. belegter Speicherplatz freigegeben wird (->"Memory Leak").
Das Problem könnte man auch über ein placement-new lösen:
Allerdings sehe ich darin keinen Vorteil//#include <new> X(const X &other) : m(::operator new[sizeof(T)]) { try { m = new(m) T(other.m); } catch(...) { ::operator delete (m); throw; } } ~X() { if(m) { m->~T(); ::operator delete(m); } }bb
edit: im normalfall sieht der DTor von X natürlich so aus:
~X() { delete m; }nicht, dass du den vergisst^^
du solltest aber daran denken, dass du nicht nur CopyCTor sondern auch op= überladen musst (das löst man am besten über das ->"Copy and swap Idiom").
-
chewbo schrieb:
ich habe einen Zeiger auf eine Klasse. In dieser Klasse sind weitere Zeiger vorhanden.
Wie bekomme ich jetzt eine 1 zu 1 Kopie von der Klasse hin? Wenn ich normal kopiere werden natürlich die Zeiger mitkopiert, diese zeigen dann aber natürlich nach Destruktion der Klasse ins Leere.Das klingt danach, als ob das Objekt für die Verwaltung der anderen Objekte zuständig ist (Du zerstörst sie ja im Destruktor, wenn ich das richtig rausgelesen habe). Beachte einfach die Dreierregel und alles wird gut.
Falls Dein Zeiger vom Typ ABC* ist, wobei ABC eine abstrakte Klasse ist, kannst Du in der Klasse noch eine virtuelle clone-Funktion hinzufügen, in etwa so:
class ABC { public: virtual ~ABC() {} virtual ABC* clone() const = 0; ... };Das sind übrigens C++ Basics. Schnapp Dir ein schlaues Buch und lerne.
Gruß,
SP
-
unskilled schrieb:
eigtl würde
X(const X &other) { m = new T(other.m); }reichen,
Tut es auch!
unskilled schrieb:
allerdings können hier an 2 Stellen Exceptions fliegen: Beim Speicher anfordern und im Copy-CTor von T. Also könnte es sein, dass der Speicher (erfolgreich) angefordert wurde und dann ne Exception fliegt und du ein Speicherleck hast, da für nicht fertig erstellte Objekte kein Destruktor erstellt wird und somit auch kein evtl. belegter Speicherplatz freigegeben wird (->"Memory Leak").
Falsch! Wenn ein Konstruktor bei "
new T(...)" eine Ausnahme wirft, wird der Speicher automatisch wieder freigegeben.edit: unskilled spricht hier -- so wie ich -- von dem Speicher, der für das T-Objekt reserviert, nicht von Speicher, der innerhalb des Konstruktors reserviert werden könnte.
unskilled schrieb:
Das Problem könnte man auch über ein placement-new lösen:
[...scheußlicher Programmcode...]
Gruß,
SP
-
Sebastian Pizer schrieb:
unskilled schrieb:
allerdings können hier an 2 Stellen Exceptions fliegen: Beim Speicher anfordern und im Copy-CTor von T. Also könnte es sein, dass der Speicher (erfolgreich) angefordert wurde und dann ne Exception fliegt und du ein Speicherleck hast, da für nicht fertig erstellte Objekte kein Destruktor erstellt wird und somit auch kein evtl. belegter Speicherplatz freigegeben wird (->"Memory Leak").
Falsch! Wenn ein Konstruktor bei "
new T(...)" eine Ausnahme wirft, wird der Speicher automatisch wieder freigegeben.Ich glaub er meint den innerhalb des Copy-Ctor angeforderten Speicher. Wenn später im Ctor dann eine Exception fliegt ist der tatsächlich verloren.
-
Sebastian Pizer schrieb:
Falsch! Wenn ein Konstruktor bei "
new T(...)" eine Ausnahme wirft, wird der Speicher automatisch wieder freigegeben.Diese Aussage würde ich schlicht und ergreifend als Falsch, oder zumindest als stark Missverständlich (gerade Anfängern gegenüber) interpretieren:
class A { private: T1 * p1; T2 * p2; public: A() : p1(new T1()), p2(new T2()) {} //... }Es stimmt zwar das der Speicherplatz der beiden Zeiger egal wie aufgeräumt wird, nicht aber die Objekte auf die sie verweisen. Wenn bei der Konstruktion von p2 eine Exception geworfen wird, wird der Speicher auf den p1 zeigt NICHT aufgeräumt. Um dies zu automatisieren braucht es schon RAII-Techniken (Smartpointer...).
-
asc schrieb:
Sebastian Pizer schrieb:
Falsch! Wenn ein Konstruktor bei "
new T(...)" eine Ausnahme wirft, wird der Speicher automatisch wieder freigegeben.Diese Aussage würde ich schlicht und ergreifend als Falsch, oder zumindest als stark Missverständlich (gerade Anfängern gegenüber)
Du hast die Aussage aus dem Kontext genommen. Der Speicher, von dem sowohl unskilled als auch ich rede ist der, der über new für das zu entstehende T-Objekt reserviert worden ist. Um weiteren Missverständnissen vorzubeugen, habe ich das nochmal in dem vorherigen Post besonders betont.
T hat (siehe unskilled's Beispiel) einfach Ausnahme-sicher zu sein. Wenn es das nicht ist, kann man innerhalb von X auch nichts mehr retten -- auch nicht mit einem Placement-New.
Gruß,
SP
-
Sebastian Pizer schrieb:
Der Speicher, von dem sowohl unskilled als auch ich rede ist der, der über new für das zu entstehende T-Objekt reserviert worden ist.
korrekt - wusste nicht, dass der speicher für das objekt an sich automatisch wieder freigegeben wird, wenn im ctor eine exception geworfen wird...
danke für die richtigstellungbb