![]() |
Unterschied Pointer/Referenzvariablen
heho hab mal ne Frage,
kann mir jemand genau erklären, wo der Unterschied zwischen Pointern und Referenzvariablen auf Objekte liegt? Beide enhalten doch gewissermaßen Referenzen auf Objekte. Was kann ich mit Pointern machen was ich mit Referenzvariablen nicht machen kann, oder umgekehrt? Oder habe ich da einfach prinzipiell was falsch verstanden? unter Pointern verstehe ich:
Delphi-Quellcode:
unter Referenzvariablen:
PMyClass = ^TMyClass;
Delphi-Quellcode:
thx schonmal im voraus
var fubar: TMyClass;
Kora |
Re: Unterschied Pointer/Referenzvariablen
Hallo und Herzlich Willkommen in der Delphi-PRAXiS!
Das Geheimnis, welches Delphi gut vor einem verbirgt, lautet: Eine Objektreferenz ist ein Pointer. Somit ist also bei
Delphi-Quellcode:
PMyClass ein Pointer auf einen Pointer.
PMyClass = ^TMyClass;
Gruß xaromz |
Re: Unterschied Pointer/Referenzvariablen
[entfernt]
|
Re: Unterschied Pointer/Referenzvariablen
in delphi sind alle klassen die mit dem schlüsselwort "class" deklariert wurden bereits pointer auf die interne repräsentation der klasse.
wenn du jetzt einen pointer auf tsomeclass nimmst hast du also nicht nur einen pointer auf diese struktur sondern einen pointer auf einen pointer auf eine solche struktur. im normalen gebrauch macht das keinerlei sinn und bietet lediglich fehlerquellen. wo es aber sinn macht ist bei funktionsparametern:
Delphi-Quellcode:
wäre aObject kein pointer so würde in der letzten lediglich die lokale kopie verändert werden. der aufrufer der myProcedure aufgerufen hat würde von der veränderung nichts mitkriegen. jetzt existiert aber nur eine lokale kopie des pointers nicht aber der objektreferenz. diese kann ich also ändern und der aufrufer wird entsprechend feststellen daß hinter dem pointer jetzt ein anderes objekt steckt.
procedure myProcedure(aObject: PSomeClass);
begin // hier kann ich den pointer dereferenzieren und auf die member zugreifen aObject^.SomeMethod; // oder ich kann ein anderes Objekt in meinen dereferenzierten Pointer stecken aObject^ := TSomeClass.Create; end; das ganze ist syntaktisch gleichbedeutend mit einem var parameter:
Delphi-Quellcode:
bei einem var parameter kann ich mir lediglich das dereferenzieren sparen der effekt ist aber der gleiche.
procedure myProcedure(var aObject: TSomeClass);
begin aObject.SomeMethod; aObject := TSomeClass.Create; end; c++ kenntnisse können hier hilfreich sein da man dort eine klare trennung zwischen objekten und objektreferenzen hat. |
Re: Unterschied Pointer/Referenzvariablen
Zitat:
|
Re: Unterschied Pointer/Referenzvariablen
Zitat:
Zitat:
Zitat:
|
Re: Unterschied Pointer/Referenzvariablen
ok danke hat meine Frage soweit beantwortet. Würde mich nur noch interessieren an einem konkreten Beispiel, wo ich Pointer dann sinnvoll (außerhalb von Objekten?) benutzen kann.
Kora |
Re: Unterschied Pointer/Referenzvariablen
@GünterS:
das ist schon immer so. führe folgenden code aus:
Delphi-Quellcode:
dir ist wahrscheinlich genau das passiert, was viele bei objekten zunächst nicht verstehen nämlich daß es nur eine objektreferenz deren objekt ich zwar manipulieren kann die ich aber selbst nicht ändern kann weil sie lediglich eine lokale kopie ist.
type
TSomeClass = class data: Integer; end; procedure DoSomething(aObject: TSomeClass); begin aObject := TSomeClass.Create; aObject.data := 42; end; procedure TForm1.Button1Click(Sender: TObject); var obj: TSomeClass; begin obj := TSomeClass.Create; obj.data := 23; DoSomething(obj); ShowMessage(obj.data); end; @Kouran: außer in altem code gar nicht. einige winapi funktionen verlangen noch pointer auf strukturen aber prinzipiell kannst du alles was mit pointern möglich ist auch mit objekten erreichen. zum beispiel kannst du verkettete listen mit objekten genauso machen wie mit pointern auf records und es macht für die funktionalität keinerlei unterschied. das heißt du kannst mittlerweile fast komplett ohne pointer programmieren. das prinzip solltest du dennoch verstehen weil es dir bei objekten begegnet. |
Re: Unterschied Pointer/Referenzvariablen
Ich persönlich benutze Pointer selten nur für Datentypen, sondern eher für Pointer auf Funktionen, die sich eben als Event registrieren oder Ähnliches. Definitiv sind Pointer auch nützlich, wenn man eben anfängt mit dynamischen Datenstrukturen zu arbeiten, also Bäume implementiert etc ( siehe New, Dispose, GetMem, FreeMem )
Anschließen kann ich mich jedoch meinen Vorrednern - imho ist das alles in C++ sichtbarer, auch wenn es natürlich etwas Einarbeitung am Anfang benötigt. Grüße |
Re: Unterschied Pointer/Referenzvariablen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Hab ihn als Anhang angehängt. Man wird darin sehen, dass es keinen Unterschied macht ob ich nun "var MyOBJ: TMyClass" oder "MyObj: TMyClass" schreibe man wird sehen, dass es einen Unterschied macht ob ich nun "myInt: integer" oder "var myInt: integer" schreibe. Hm Ok, in meinem Beispiel sieht man auch schön den Unterschied zwischen dem was Frickeldrecktuxer_TM geschrieben hat und dem was ich da gmacht habe. Wenn man nicht ausgerechnet die Klasse in der Methode erzeugt oder austauschen möchte, sondern lediglich mit dem Objekt arbeiten möchte, dann macht das schon einen Unterschied. |
Re: Unterschied Pointer/Referenzvariablen
Zitat:
|
Re: Unterschied Pointer/Referenzvariablen
Versuch deinem Objekt nil zuzuweissen in deine Prozedur.
Delphi-Quellcode:
procedure myProc( obj:TObject );
begin obj := nil; end; // var o:TObject; begin o := TObject.Create(); myProc( o ); if o<>nil then Application.MessageBox('sniper hatte recht','sniper'); o.free; end; |
Re: Unterschied Pointer/Referenzvariablen
Hallo Günter,
keiner hier hat behauptet, dass es keinen Unterschied macht, ob Du Parameter mit var oder ohne übergibst. Der Unterschied zwischen Objekten und primitiven Typen ist der, dass ein Objekt eigentlich ein Pointer ist und damit var unnötig ist, um die Member eines Objektes zu verändern. Es wird ja nicht das Objekt kopiert und lokal verwendet, sondern tatsächlich das übergebene Objekt verwendet. Damit kann ich das Objekt manipulieren; wenn Du aber die Objektreferenz selbst ändern möchtest, dann musst Du natürlich var verwenden. |
Re: Unterschied Pointer/Referenzvariablen
genau:
Delphi-Quellcode:
procedure Test1(AObj: TObject);
begin AObj := TObject.Create; end; procedure Test2(var AObj: TObject); begin AObj := TObject.Create; end; var O1, O2: TObject; begin O1 := TObject.Create; O2 := O1; Test1(O1); // hier ist O1 = 02: if O1 = O2 then ShowMessage('Hah ;D '); O1 := TObject.Create; O2 := O1; Test2(O1); //hier ist O1 <> O2 if O1 <> O2 then ShowMessage('Hah ;D '); end; |
Re: Unterschied Pointer/Referenzvariablen
Liste der Anhänge anzeigen (Anzahl: 1)
Ja ok, ich gebs ja zu ... befand mich ein wenig am Irrweg. Konnte man aber deutlich an meinem Beispiel sehen und für diese Fälle ists ja wirklich wurscht.
Hab diese zwei Varianten auch noch dazugepackt in mein TestProjekt, kann man sich anhand des Quellcodes gut anschaun. Vielleicht hilf diese Diskussion ja auch noch jemand anderen, diese "Falle" zu vermeiden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz