Einzelnen Beitrag anzeigen

Muetze1
(Gast)

n/a Beiträge
 
#4

Re: TObject kopieren und zuweisen

  Alt 16. Jun 2004, 12:00
Moin!

Code:
p := s;
Durch diese Zuweisung überschreibst du aber die angelegte Instanz von p und somit hast du in p und in s danach einen Instanzenzeiger auf ein und das selbe Objekt, nämlich s. Würde dieser Code in C++ geschrieben werden (vorausgesetzt die beiden Objekte sind nicht als "Zeiger auf" definiert), dann würde C++ automatisch den CopyConstructor aufrufen und bei p ein neues Objekt anlegen, welches den Inhalt von s übernimmt.

Die beiden Variablen s und p sind intern nur Zeiger auf die Objekte und durch die Zuweisung überschreibst du den einen Zeiger. Mit anderen Worten: Intern hast du zwar immer noch irgendwo im Speicher beide Instanzen rumliegen, weisst aber nur noch von s wo diese liegt (weil p und s darauf zeigen). Du hast dann keine Möglichkeit mehr zu wissen, wo denn die Instanz vom originalen p liegt.

Nochwas: Um das zu verdeutlichen sollte eigentlich deine Freigabe am Ende schief gehen:
Code:
s.Free
p.Free
Da s und p auf die gleiche Instanz zeigen, gibt s.Free die Instanz frei und danach probiert das p auch nochmal, aber da existiert dort keine Instanz mehr, also wird das fehlschlagen mit einer EAccessViolation an einer ziemlich krummen Adresse (die wo vorher die Instanz mal lag).

Nochwas:
Code:
s.zahl := 12;
p.zahl := 12589;
Nachdem du s.zahl die 12 zugewiesen hast, kannst du ja mal vor der Ausführung der nächsten Anweisung (12589 auf p.Zahl zuweisen) mal nachschauen was p.Zahl für einen Wert hat: Ich vermute mal ganz stark 12...

Lösung zu deinem Problem:

Lege dir entweder einen CopyConstructor an oder bastle dir einen Assign Methode...

Bsp Copy Constructor:
Delphi-Quellcode:
Type
  TMember = Class
  Public
    Zahl : Integer;

    Constructor Create; Overload; // normaler Constructor
    Constructor Create(AMember : TMember); Overload; // Copy Constructor
  End;

.....

Constructor TMember.Create(AMember : TMember);
Begin
  inherited Create;

  Zahl := AMember.Zahl; // alles kopieren was an Vars definiert ist
End;
Dann kannst du deine Kopier so anlegen:

  p := TMember.Create(s); // copy constructor aufrufen Nochwas dazu:
Wenn deine TMember Klasse auch private oder Protected Variablen besitzt die auch kopiert werden sollen aber ja nach aussen nicht sichtbar sind (da private/protected), so kannst du diese trotzdem im Constructor kopieren und drauf zugreifen, da alle Klassen in einer Unit untereinander friend Klassen sind. In C++ müsstest du sowas extra noch definieren, Delphi hat das einfach über die Unit gelöst...

MfG
Muetze1
  Mit Zitat antworten Zitat