PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Delphi: automatische by-reference-Übergabe?


Vedek Bareil
2004-10-07, 23:00:28
Hallo,

ich habe vor einer Weile unter Delphi eine bemerkenswerte Feststellung gemacht:
In einem Demo-Programm wurde eine Zeichenfläche (TPaintBox-Objekt) als Parameter an den Konstruktor eines Threads (TThread) übergeben, von den dann eine Methode auf die Zeichenfläche zeichnete. Kann es sein, daß Delphi in solchen Fällen intern automatisch eine by-reference-Übergabe realisiert, etwa immer dann, wenn eine VCL-Komponente als Parameter übergeben wird?
Wäre die PaintBox by value übergeben worden, hätte der Thread ja nur in eine Kopie gezeichnet, die sichtbare PaintBox auf dem Programmfenster wäre davon unbeeinflußt geblieben...

In Pascal/Delphi werden by-reference-Übergaben ja üblicherweise dadurch realisiert, daß in der Parameterliste der Funktion, an die übergeben wird, das Schlüsselwort var vor dem betreffenden Parameter steht. Das war in dem besagten Demo-Programm nicht der Fall. Hier schematisch der Code:

type TThread1 = class(TThread)
private
FBox: TPaintBox;
//...
protected
procedure Execute; override;
//...
public
construcotr Create(Box: TPaintBox; {...})
end;

//...

constructor TThread1.Create(Box: TPaintBox; {...});
begin
FBox := Box;
//...
end;

//...

procedure TThread1.Execute;
begin
// Zeichnen auf FBox
end;

Xmas
2004-10-08, 01:27:38
Object Pascal-Sprachreferenz
Klassentypen

Der Wert eines Klassentyps wird als 32-Bit-Zeiger auf eine Instanz der Klasse gespeichert.

Jaja, der leidige Unterschied zwischen Wert- und Referenztypen. Variablen, die Instanzen einer Klasse halten, sind in Object Pascal genauso wie in Java oder C# Referenzen auf diese Instanz (C# kennt aber auch struct als Werttyp statt class).

Diese Referenz wird dann by Value übergeben. Das heißt du kannst innerhalb einer Funktion die Instanz beeinflussen, aber nicht ändern auf welche Instanz die Referenz zeigt.

icemanemp
2004-10-08, 08:45:25
Werden den nicht alle Objekte bei Delphi, wenn man var weglässt als Referenz übergeben?! Value würde das ganze doch ganz schön verlangsamen! Ganze Objekte übergeben ist doch schon ein bischen was... dann müsste man sich ja auch noch um die Zerstörung dort kümmern! So hat man doch lediglich den Pointer als Zahl übergeben, was viel schlanker ist und die procedure oder funktion muss sich gar nicht um die Zerstörung kümmern...

Crushinator
2004-10-08, 11:35:36
Richtig, Objekte werden in Delphi den Funktionen und Prozeduren als Referenz übergeben, einfache Variablen jedoch als Wert, solange sie in der Parameterliste nicht ausdrücklich mit var oder const deklariert würden.

Vedek Bareil
2004-10-09, 00:24:42
ist es in Delphi denn auch möglich, Objekte by value zu übergeben? Ich hatte schon Situationen, wo das nötig oder zumindest sinnvoll war (in C++, nicht Delphi).

Xmas
2004-10-09, 21:01:20
ist es in Delphi denn auch möglich, Objekte by value zu übergeben? Ich hatte schon Situationen, wo das nötig oder zumindest sinnvoll war (in C++, nicht Delphi).
AFAIK nicht. Aber by value heißt, du bekommst eine Kopie des Objekts. Die kannst du auch manuell erzeugen.

Vedek Bareil
2004-10-10, 02:06:26
Hey XMas, danke für die Hilfe :)

Dein Tip führt mich auf eine weitere Frage: wie steht es eigentlich um die Möglichkeit, Klassentypen für Rückgabewerte von Funktionen zu verwenden?
Im Rahmen meiner Diplomarbeit habe ich z.B. in C++ die Vektorklasse aus der STL zur Realisierung von vektorwertigen Funktionen verwendet:

#include <vector>
using namespace std;

//...

vector<double> function_vector(/*...*/)
{
vector<double> ReturnVector(Dim);
//...
return ReturnVector;
}
Auf die Idee, es so zu machen wie in C üblich, nämlich einen vektoriellen Rückgabewert gar nicht als Rückgabewert zu implementieren, sondern als by-reference-Parameter:

void function_vector(double ReturnVector[], /*...*/)
war ich schlicht nicht gekommen :D

icemanemp
2004-10-11, 13:37:34
Klassentypen als Rückgabewert ist auch kein Problem bei Delphi! Ist ne ganz normale Sache... Entweder direkt ne Funktion benutzen oder dein Objekt bei Reference übergeben und damit arbeiten! Bei dem einen musst du es in der Funktion erstellen und ausserhalb zerstören, bei dem anderen musst du es immer ausserhalb zerstören, ausser die machst das in deiner procedure, aber das dürfte ja alles nur thoerie für dich/euch sein!