| Autor |
Beitrag |
sky21
      
Beiträge: 141
W7
D2010, XE2
|
Verfasst: Di 28.07.09 15:30
Ich habe ein Blackout bezüglich "Speicherfreigabe".
Es geht um Folgendes: Ich instanziere ein Objekt und übergebe dies einer Funktion CheckIt(). Was macht aber CheckIt() genau? Meiner Meinung nach eine lokale Kopie. D.h. ich habe dann 2x die Daten, richtig? Was bewirkt dann ein Free() auf dem übergebenen Objekt? was konkret wird jetzt freigegeben? Ich schnall's im Moment echt nicht.
PS: ...hab mir gerade überlegt, ob es einfacher wäre, einfach Pointers zu übergeben ...
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| type PClassBase = ^TClassBase; TClassBase = class(Tobject) public procedure foo(aVal : Integer); constructor Create; end;
type PClassSubA = ^TClassSubA; TClassSubA = class(TClassBase) public constructor Create; end; type PClassSubB = ^TClassSubB; TClassSubB = class(TClassBase) public constructor Create; end; |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TForm2.ButtonClick(Sender: TObject); begin Checkit( TClassSubB.Create() ); end;
procedure TForm2.Checkit(obj : TClassBase); begin
if (obj is TClassSubA) then begin obj.foo(1); end else if (obj is TClassSubB) then begin obj.foo(2); end else begin obj.foo(-1); end;
obj.free; end; |
|
|
Tastaro
      
Beiträge: 414
Erhaltene Danke: 23
|
Verfasst: Di 28.07.09 15:52
In deinem Fall hast due das Objekt nur genau 1x und es wird durch das .free in checkit freigegeben.
Ist möglich, aber nicht schön, da imemr da freigegeben werden sollte wo auch erzeugt wird.
Also wäre das viel hübscher:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| procedure TForm2.ButtonClick(Sender: TObject); var CheckObject: TClassSubB; begin CheckObject := TClassSubB.Create(); Checkit( CheckObject ); CheckObject.free; end;
procedure TForm2.Checkit(obj : TClassBase); begin
if (obj is TClassSubA) then begin obj.foo(1); end else if (obj is TClassSubB) then begin obj.foo(2); end else begin obj.foo(-1); end; end; | [/quote]
Achja: Und Zeiger braucht man gar nicht, wenn man Objekte hat.
Beste Grüße
|
|
sky21 
      
Beiträge: 141
W7
D2010, XE2
|
Verfasst: Di 28.07.09 16:01
Danke für die schnelle Antwort. Ich bin da vollkommen gleicher Meinung, dass Erzeugung und Zerstörung im selben Codeblock erfolgend sollte. Aber das geht ja nur, wenn die Abarbeitung (z.b. dann bei CheckIt()) synchron funktioniert.
Trotzdem eine Verständnisfrage:
Was genau wird eigentlich der Funktion übergeben? Lokele Kopie? Adresse? Ich bin da noch verwirrt, denn üblicherweise arbeite ich in solchen Fällen dann mit dem "var" Zusatz.
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 28.07.09 16:04
Moin!
Bitte ändere den Titel des Topics, da er wenig über das eigentlich Thema verrät. Hier der entsprechende Absatz aus den Richtlinien:
| 1.2 Beiträge: | | Bitte formuliere den Betreff Deiner Beiträge so, dass andere Mitglieder anhand dieser bereits das eigentliche Thema festmachen können. Beiträge wie etwa "Eine Anfängerfrage" oder "Weiß jemand, wie das geht?" lassen den Leser im Unklaren darüber, was das Thema der Diskussion ist.[...] |
Einfach oben bei Deinem ersten Beitrag auf  oder  klicken und den Titel ändern. Danke Dir!
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Tastaro
      
Beiträge: 414
Erhaltene Danke: 23
|
Verfasst: Di 28.07.09 16:07
sky21 hat folgendes geschrieben : | Danke für die schnelle Antwort. Ich bin da vollkommen gleicher Meinung, dass Erzeugung und Zerstörung im selben Codeblock erfolgend sollte. Aber das geht ja nur, wenn die Abarbeitung (z.b. dann bei CheckIt()) synchron funktioniert.
Trotzdem eine Verständnisfrage:
Was genau wird eigentlich der Funktion übergeben? Lokele Kopie? Adresse? Ich bin da noch verwirrt, denn üblicherweise arbeite ich in solchen Fällen dann mit dem "var" Zusatz. |
Übergeben wird eine sog. Referenz. Also keine Kopie des Objekts, sondern nur ein Verweis darauf.
Siehe auch:
de.wikipedia.org/wik...eferenz_(Informatik)
Beste Grüße
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: Di 28.07.09 20:16
sky21 hat folgendes geschrieben : | | Was genau wird eigentlich der Funktion übergeben? Lokele Kopie? Adresse? |
Adresse.
sky21 hat folgendes geschrieben : | | Ich bin da noch verwirrt, denn üblicherweise arbeite ich in solchen Fällen dann mit dem "var" Zusatz. |
Da du dazu auch noch mit Pointers arbeitest, solltest du dir eines klarmachen: TObject = Pointer. Objektinstanzen sind immer nur Verweise auf die Objekte selbst. Da diese im RAM liegen und das auch tun müssen, können sie nicht einfach als Parameter übergeben werden (Parameter sind im Stack).
Wenn du dennoch sogenannte Wertetypen bzw. Werteparameter brauchst, dann nimm Records.
Pass aber auf, dass du keine dynamischen Arrays dadrin verwendest, denn die sind wieder Referenztypen - das hat mir mehrere Stunden nervige Fehlersuche eingebracht 
|
|
Tastaro
      
Beiträge: 414
Erhaltene Danke: 23
|
Verfasst: Di 28.07.09 23:36
Yogu hat folgendes geschrieben : | sky21 hat folgendes geschrieben : | | Was genau wird eigentlich der Funktion übergeben? Lokele Kopie? Adresse? |
Adresse.
|
Nein, eine Referenz. Siehe de.wikipedia.org/wik...enz_%28Informatik%29
Yogu hat folgendes geschrieben : | sky21 hat folgendes geschrieben : | | Ich bin da noch verwirrt, denn üblicherweise arbeite ich in solchen Fällen dann mit dem "var" Zusatz. |
Da du dazu auch noch mit Pointers arbeitest, solltest du dir eines klarmachen: TObject = Pointer.
|
TObjekt ist eine Klasse und kein Objekt. Das hat erst mal gar nix mit Zeigern zu tun.
Legt man eine Instanz der Klasse an, erhält man eine Referenz für ein Objekt. Dass das irgendwo ein Zeiger wird braucht aber einen Entwickler der in Delphi schreibt erst mal gar nicht zu interessieren, denn für den sind Referenzen und Zeiger zwei ganz verschiedenen Dinge.
Yogu hat folgendes geschrieben : |
Objektinstanzen sind immer nur Verweise auf die Objekte selbst. Da diese im RAM liegen und das auch tun müssen, können sie nicht einfach als Parameter übergeben werden (Parameter sind im Stack).
|
Verweise (= Referenzen) ermöglichen zwar den Zugriff auf Instanzen von Objekte, aber dadurch sind die Verweise nicht identisch mit Instanzen. Diese Verweise lassen sich sehr wohl ganz einfach als Parameter übergeben. (siehe oben)
Yogu hat folgendes geschrieben : |
Wenn du dennoch sogenannte Wertetypen bzw. Werteparameter brauchst, dann nimm Records.
Pass aber auf, dass du keine dynamischen Arrays dadrin verwendest, denn die sind wieder Referenztypen - das hat mir mehrere Stunden nervige Fehlersuche eingebracht  |
Ich bin der festen Überzeugung, dass man keine Records braucht, wenn man Klassen hat. Aber da gehen die Meinungen hin und wieder auseinander.
Beste Grüße
|
|
Boldar
      
Beiträge: 1555
Erhaltene Danke: 70
Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
|
Verfasst: Di 28.07.09 23:46
Tastaro hat folgendes geschrieben : |
Ich bin der festen Überzeugung, dass man keine Records braucht, wenn man Klassen hat. Aber da gehen die Meinungen hin und wieder auseinander. |
Naja, es gibt auch Gelegenheiten, wo eine eigene Klasse mit Kanonen auf Spatzen geschossen wäre.
Oder würdest du TPoint als Klasse implementieren?
mfg Boldar
|
|
Tastaro
      
Beiträge: 414
Erhaltene Danke: 23
|
Verfasst: Mi 29.07.09 07:28
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 29.07.09 11:26
Moin!
Tastaro hat folgendes geschrieben : | | Ich bin der festen Überzeugung, dass man keine Records braucht, wenn man Klassen hat. |
Theoretisch: ja, praktisch: nein.  Bedien´ mal die Windows-API ohne records...
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: Mi 29.07.09 11:31
Naja, laut Wikipedia ist eine Referenz ein Zeiger, mit dem es sich leichter arbeiten lässt und der weniger fehleranfällig ist. Technisch gesehen ist das eigentlich kein großer Unterschied.
Tastaro hat folgendes geschrieben : | Yogu hat folgendes geschrieben : | sky21 hat folgendes geschrieben : | | Ich bin da noch verwirrt, denn üblicherweise arbeite ich in solchen Fällen dann mit dem "var" Zusatz. |
Da du dazu auch noch mit Pointers arbeitest, solltest du dir eines klarmachen: TObject = Pointer.
|
TObjekt ist eine Klasse und kein Objekt. |
TObject ist ein Datentyp. Deklariert man eine Variable des Typs TObject, beschreibt diese Variable eine Referenz, also eine Art Zeiger. Man hätte theoretisch auch eine Variable des Typs Pointer deklarieren können und ihr zum Beispiel TObject.Create zuweisen können. Alles möglich.
Tastaro hat folgendes geschrieben : | | Das hat erst mal gar nix mit Zeigern zu tun. |
Genau hier ist der Punkt: Wenn man Referenz mit Zeiger gleichsetzt, stimmt das von mir geschriebene. Wenn nicht, nicht
Tastaro hat folgendes geschrieben : | | Legt man eine Instanz der Klasse an, erhält man eine Referenz für ein Objekt. Dass das irgendwo ein Zeiger wird braucht aber einen Entwickler der in Delphi schreibt erst mal gar nicht zu interessieren, denn für den sind Referenzen und Zeiger zwei ganz verschiedenen Dinge. |
Stimmt natürlich, aber es kann ihn interessieren und mich tut es das
Tastaro hat folgendes geschrieben : | Yogu hat folgendes geschrieben : |
Objektinstanzen sind immer nur Verweise auf die Objekte selbst. Da diese im RAM liegen und das auch tun müssen, können sie nicht einfach als Parameter übergeben werden (Parameter sind im Stack).
|
Verweise (= Referenzen) ermöglichen zwar den Zugriff auf Instanzen von Objekte, aber dadurch sind die Verweise nicht identisch mit Instanzen. Diese Verweise lassen sich sehr wohl ganz einfach als Parameter übergeben. (siehe oben) |
Ok, ich meinte nicht Objektinstanzen, sondern Variablen des Typs TObject. Hab' mir irgendwann mal in den Kopf gesetzt, dass Variablen Instanzen sind. Das ist irreführend.
Tastaro hat folgendes geschrieben : | Yogu hat folgendes geschrieben : |
Wenn du dennoch sogenannte Wertetypen bzw. Werteparameter brauchst, dann nimm Records.
Pass aber auf, dass du keine dynamischen Arrays dadrin verwendest, denn die sind wieder Referenztypen - das hat mir mehrere Stunden nervige Fehlersuche eingebracht  |
Ich bin der festen Überzeugung, dass man keine Records braucht, wenn man Klassen hat. Aber da gehen die Meinungen hin und wieder auseinander. |
Stimmt schon, wer Records benutzt, ist faul. Zu faul, die Instanzen zu initialisieren, zu faul, um eine Zuweisung à la Assign durchzuführen etc. Mit OOP haben Records wenig zu tun. Aber ich schweife vom Thema ab.
Grüße,
Yogu
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 29.07.09 11:31
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 29.07.09 11:33
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: Mi 29.07.09 12:15
@Records oder Klassen:
In sprachen wie C++ trifft es zu das records/structs überflüssig sind (wobei es da afaik sowieso intern vom compiler identisch behandelt wird.. nur das beim record per standard alles public, bei der klasse alles private ist)..
Bei Delpti allerdings macht es einen riesen Unterschied ob man Records oder Klassen benutzt!
Klassen werden jedesmal via create() erzeugt und landen somit im RAM, jeder zugriff darauf dauert länger als auf einen Record der im Stack liegt. Das mag bei 0815-Anwendungen egal sein.. aber für aufwändige Algorithmen oder Spiele etc ist das ein riesen Zeitgewinn/verlust.
Aya
_________________ Aya
I aim for my endless dreams and I know they will come true!
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 29.07.09 12:20
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|