Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Parameterübergabe - leichte Verwirrung (https://www.delphipraxis.net/61062-parameteruebergabe-leichte-verwirrung.html)

rowkajjh 16. Jan 2006 16:54


Parameterübergabe - leichte Verwirrung
 
Hallo,

wenn man was nicht ganz versteht, macht man sich ja ein Beispiel ;-)
Ich komme mit Proceduren und wann übergebene Parameter verändert werden noch nicht ganz klar. Mein Beispiel:

Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils,Graphics;

Procedure cbCopy(i : Integer);
begin
  i := 1;
end;

Procedure cbVal(var i : Integer);
begin
  i := 2;
end;

Procedure cbCopyImg(img : TBitmap);
begin
  img.Width := 20;
  img.Height := 20;;
end;

Procedure cbValImg(var img : TBitmap);
begin
  img.Width := 30;
  img.Height := 30;
end;

var
  i  : Integer;
  img : TBitmap;
begin
  i := 0;
  writeln(Format('i:%d', [i]));

  cbCopy(i);
  writeln(Format('i:%d', [i]));

  cbVal(i);
  writeln(Format('i:%d', [i]));

  img := TBitmap.Create;
  img.Width := 10;
  img.Height := 10;
  writeln(Format('w:%d h:%d', [img.Width, img.Height]));

  cbCopyImg(img);
  writeln(Format('w:%d h:%d', [img.Width, img.Height]));

  cbValImg(img);
  writeln(Format('w:%d h:%d', [img.Width, img.Height]));

  FreeAndNil(img);
  Readln;
end.
Das 'i' bei cbCopy nicht und bei cbVal verändert wird, ist mir sofort logisch. Aber bei img nicht so. Dieses ist ja nach beiden Proceduren verändert. Liegt das darin, daß img eine Art Zeiger auf ein TBitmap-Objekt ist, und wenn ich einen Zeiger kopiere, dann kann ich natürlich den Inhalt, auf den der Zeiger zeigt, ändern?

Wenn ich den Zeiger selbst in der Procedure umbiegen würde (also auf was anderes zeigen), da würde das Ergebnis bei den beiden Proceduren unterschiedlich aussehen, oder?

Jetzt, wo ich das schriebe, wirds mir langsam klar. Ist meine Erkärung so richtig?

Danke!

Wenn ich was mit
OBJECT i; und i := OBJECT.Create anlege, kann ich das dann in allen Proceduren ändern?

alzaimar 16. Jan 2006 17:03

Re: Parameterübergabe - leichte Verwirrung
 
Zitat:

Zitat von rowkajjh
... Aber bei img nicht so. Dieses ist ja nach beiden Proceduren verändert. Liegt das darin, daß img eine Art Zeiger auf ein TBitmap-Objekt ist, und wenn ich einen Zeiger kopiere, dann kann ich natürlich den Inhalt, auf den der Zeiger zeigt, ändern?...

Genauso ist es. Es hat bei mir auch einige Zeit gedauert (und genau so ein Aha-Erlebnis), bis ich auf den Trichter mit den Objekten und Zeigern gekommen bin.

Noch ein Tipp: Wenn Du genau wissen willst, was sich hinter einer Variable befindet, benutze
Delphi-Quellcode:
SizeOf (AnyVarOrType)
. Damit siehst Du am Besten, was sich genau hinter einer Variable oder einem Parameter verbirgt.

Ach, und was Du sonst noch angenommen hast, stimmt auch A-L-L-E-S :thumb:

RavenIV 16. Jan 2006 17:14

Re: Parameterübergabe - leichte Verwirrung
 
Du hast Recht.
Wenn man einen Basistyp (int, string, real und Untertypen) ohne "var" übergibt, wird eine Kopie angelegt.

Bei Objekten oder komplexen Datentypen wird eine Kopie auf das Original übergeben, egal ob man "var" benutzt oder nicht.

Das ist halt bei Delphi so, in anderen Sprachen mag das anderst gelöst sein...

rowkajjh 16. Jan 2006 17:47

Re: Parameterübergabe - leichte Verwirrung
 
Zitat:

Zitat von RavenIV
Du hast Recht.
Wenn man einen Basistyp (int, string, real und Untertypen) ohne "var" übergibt, wird eine Kopie angelegt.

Bei Objekten oder komplexen Datentypen wird eine Kopie auf das Original übergeben, egal ob man "var" benutzt oder nicht.

Das ist halt bei Delphi so, in anderen Sprachen mag das anderst gelöst sein...

Ist ja okay so. Wenn mans weiß...

Danke an alle!

Khabarakh 16. Jan 2006 18:23

Re: Parameterübergabe - leichte Verwirrung
 
Zitat:

Zitat von RavenIV
Wenn man einen Basistyp (int, string, real und Untertypen) ohne "var" übergibt, wird eine Kopie angelegt.

Nicht nur die einfachen Typen (wobei string nicht zu ihnen gehört) gehören zu den sogenannten Wertetypen (<=> Referenztypen), auch statische Arrays und Records gehören dazu.
Zitat:

Das ist halt bei Delphi so, in anderen Sprachen mag das anderst gelöst sein...
Solange in der anderen Sprache ein Delphi-Wertetyp nicht zu einem Verweistyp oder andersherum wird, sollte sich eigentlich nichts Großes ändern.

rowkajjh 16. Jan 2006 18:58

Re: Parameterübergabe - leichte Verwirrung
 
Zitat:

Zitat von Khabarakh
Zitat:

Zitat von RavenIV
Wenn man einen Basistyp (int, string, real und Untertypen) ohne "var" übergibt, wird eine Kopie angelegt.

Nicht nur die einfachen Typen (wobei string nicht zu ihnen gehört) gehören zu den sogenannten Wertetypen (<=> Referenztypen), auch statische Arrays und Records gehören dazu.

Nochmehr? Oder kann man das irgendwo in der Hilfe oder sonstwo genauer nachlesen?

KHJ 18. Jan 2006 17:27

Re: Parameterübergabe - leichte Verwirrung
 
Wie der Zufall es will, bin ich auch darüber gestolpert.

Was muss ich denn machen um bei Objekten nicht das Original zu verändern sonder wirklich nur eine lokale Kopie zu erzeugen diese zu ändern und ggf. nach erst nach einer Abfrage die Änderung zu übergeben?

Gruß Karlheinz

3_of_8 18. Jan 2006 17:34

Re: Parameterübergabe - leichte Verwirrung
 
Also nochmal zu dem Var-zeugs:

Wenn du einen Klassenkonstruktor aufrufst:

TObject.Create;

Dann wird eine neue Instanz der Klasse erzeugt und ein Pointer auf diese Instanz zurückgegeben.
Also ist dann das Ergebnis von:

myObject:=TObject.Create;

Ein Pointer.

Wenn du das jetzt als Parameter übergibst, dann übergibst du diesen Pointer. Und damit greift die Routine auf die gleiche Instanz zu. Nur über einen anderen Pointer.


Wenn du jetzt das ganze mit var machst, dann übergibst du einen Pointer auf die angegebene Variable.

Bei einfachen Typen wie Strings, Integer, Real... ist das ein ^String, ^Integer, ^Real.

Bei Klassen ist das dann logischerweise immer ein ^Pointer. Also ein Pointer auf einen Pointer.


Wenn ich jetzt Müll geredet habe, sagt es mir bitte. Danke.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz