Delphi -- prozedurale Varianlen???

Diskutiere Delphi -- prozedurale Varianlen??? im Developer Network Forum im Bereich Hardware & Software Forum; Hi ich habe mich in Delphi einmal mit prozeduralen Variablen beschäftigt, und bin jetzt völlig verzweifelt, weil es mir einfach nicht gelingt sie...
  • Delphi -- prozedurale Varianlen??? Beitrag #1
D

Deep Space

Bekanntes Mitglied
Dabei seit
01.08.1999
Beiträge
2.004
Reaktionspunkte
0
Hi

ich habe mich in Delphi einmal mit prozeduralen Variablen beschäftigt, und bin jetzt völlig verzweifelt, weil es mir einfach nicht gelingt sie korrekt zu deklarieren und ständig die selbe Fehlermeldung auftritt.

hier der code:

...

type
TProcVar = function(a: integer): integer;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
function ftest(a: integer): integer;
private
{ Private-Deklarationen }
procVar: TProcVar;
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var a: integer;
begin
procVar := ftest;
a := procVar(3);
end;

function TForm1.ftest(a: integer): integer;
begin
result := a * 4;
end;

end.


jedes Mal tritt bei der Compilierung folgender Fehler in der Zeile "procVar := ftest;" auf:
"[Fehler] Unit1.pas(32): Inkompatible Typen: Reguläre Prozedur und Methodenzeiger"

kann mir jemand sagen wo da der Fehler liegen soll?

D.S.
 
  • Delphi -- prozedurale Varianlen??? Beitrag #2
O

O Love

Bekanntes Mitglied
Dabei seit
08.04.1999
Beiträge
2.286
Reaktionspunkte
0
Es ist genau so, wie es durch den Compiler angegeben wird...

Methode

Bei FTest handelt es sich um eine Methode, also eine Prozedur, die zu einer Klasse gehört. Dabei ist Form1 nur eine Instanz der Klasse TForm1, Du kannst ja noch mehr Instanzen ziehen, wobei jedesmal Speicher für die Klasse ausgefaßt wird.

Prozedur

Deine Deklaration von TProcVar ist dagegen der Typ einer "echten" Prozedur, deren Variablen Du nur eine statische Prozedur - nicht Teil einer Klasse - zuweisen kannst.

Ausweg

Du kannst Methodenzeiger deklarieren, wenn Du "of object" dranhängst. Genau das wird nämlich bei Events (Ereignissen) von Klassen/Komponenten gemacht. Ein Beispiel ist TNotifyEvent, welches so deklariert ist:

Code:
TNotifyEvent = procedure (Sender: TObject) of object;

Alles klar?

O Love

------------------
"I will not abide disobedience!"
 
  • Delphi -- prozedurale Varianlen??? Beitrag #3
D

Deep Space

Bekanntes Mitglied
Dabei seit
01.08.1999
Beiträge
2.004
Reaktionspunkte
0
aha, klingt plausibel.

bei der Gelegenheit habe ich noch einige Fragen:

1. Was ist eine Instanz?

2. Was genau ist eine Klasse (darüber habe ich mir schon oft den Kopf zerbrochen, bin aber nie zu einer eindeutigen Definition gekommen. :))

3. Wie deklariere ich eine echte Prozedur, bei der die Anfügung "of object" weggelassen werden kann?

D.S.
 
  • Delphi -- prozedurale Varianlen??? Beitrag #4
D

Deep Space

Bekanntes Mitglied
Dabei seit
01.08.1999
Beiträge
2.004
Reaktionspunkte
0
...also Frage 3 hat sich erledigt. Mein Fehler bei der Deklaration der "realen" Prozedur war, dass ich sie an das Ende des Codes gesetzt hatte.
So etwas bin ich gar nicht gewöhnt, in VB spielt die Reihenfolge der Deklarationen keine Rolle :D . Ich glaube da ist der VB-Compiler etwas flexibler und "tolleranter".

D.S.
 
  • Delphi -- prozedurale Varianlen??? Beitrag #5
O

O Love

Bekanntes Mitglied
Dabei seit
08.04.1999
Beiträge
2.286
Reaktionspunkte
0
Gut, dann gebe ich mal eine kurze Einführung ins objektorientierte Programmieren (OOP)...

Herkömmlich

Ein althergebrachtes Programm besteht aus Variablen und Prozeduren, die diese Variablen manipulieren. Jede Prozedur ist dabei eine statische, wie auch im Beispiel aufgeführt.

Code:
type
  Tkreis = record
    X, Y, R : Integer;
  end;
 
var
  Kreise : array[0..9] of TKreis;
 
procedure ZeichneKreis (X, Y, R: Integer);
begin
  Circle (X, Y, R);
end;

OOP

Bei der OOP werden die Variablen und Prozeduren nun zusammengefaßt, man bildet eine Klasse. Damit erreicht man 3 Punkte:
  • Kapselung: Du greifst nicht mehr direkt auf die Variablen der Klasse zu, sondern nur noch über die zur Klasse gehörenden Prozeduren (Methoden). Damit kannst Du z.B. die Richtigkeit der Werte sichern, wenn einer was zuweisen will. Zusätzlich kannst Du damit die Sicherheit gewährleisten. Siehe unten.
  • Vererbung: Es ist möglich, weitere Klassen von einer Elternklasse abzuleiten, diese erbt die Eigenschaften und kann andere einführen. Damit bekommst Du Ordnung in Deine Programmierung.
  • Polymorphie: Hat die abgeleitete (abgelittene) Klasse eine Methode, die denselben Header wie die in der Elternklasse hat, und überschreibst Du diese, dann wird beim Aufruf der Methode über die Instanz der Klasse immer die klasseninterne Methode verwendet, nicht die der Elternklasse. Beispiel folgt.

Begriffe

Klasse: Kombination von Variablen und Prozeduren zu einer Einheit. Analog Typ bei Nicht-OOP.

Instanz: Repräsentation einer Klasse. Aktuelles Element im Speicher. Analog Variable (vom Typ x) bei Nicht-OOP.

OOP-Beispiel

Klassen-Deklaration und Feld, wo unsere Instanzen reinkommen:

Code:
type
  TGrafikObjekt = class
    X, Y : Integer;
    constructor Create; virtual;
    procedure Zeichnen; virtual;
  end;
  TKreis = class (TGrafikObjekt)
    R : Integer;
    constructor Create; override;
    procedure Zeichnen; override;
  end;
  TRechteck = class (TGrafikObjekt)
    B, H : Integer;
    constructor Create; override;
    procedure Zeichnen; override;
  end;
 
var
  Grafiken : array[0..9] of TGrafikObjekt;

Hier sind die Methoden:

Code:
constructor TGrafikObjekt.Create;
begin
  X := 0; Y := 0;
end;
 
procedure TGrafikObjekt.Zeichnen;
begin
  // Nichts weiter machen. Dient der Demonstation von Polymorphie.
  MessageBeep (0);
end;
 
constructor TKreis.Create;
begin
  inherited; // Pascal-spezifisch, ruft die Methode der Elternklasse auf.
  R := 0;
end;
 
procedure TKreis.Zeichnen;
begin
  inherited;
  Circle (X, Y, R);
end;
 
constructor TRechteck.Create;
begin
  inherited;
  B := 0; H := 0;
end;
 
procedure TRechteck.Zeichnen;
begin
  inherited;
  Rectangle (X, Y, X + B, Y + H);
end;

So, jetzt geht's los. Es werden Instanzen der jeweiligen Klassen gebildet. Man beachte, daß die Kinder zu ihren Eltern kompatibel sind. Sie erben ja schließlich alle Eigenschaften. Umgekehrt gilt das aber nicht.

Code:
  Grafiken[0] := TKreis.Create;
  Grafiken[1] := TRechteck.Create;
  ...
  Grafiken[9] := TKreis.Create;

Wir weisen jetzt mal ein paar Werte zu:

Code:
  TKreis (Grafiken[0]).X := 100;
  TKreis (Grafiken[0]).Y := 100;
  TKreis (Grafiken[0]).R := 10;

Hier kommt jetzt die Polymorphie. Jede Instanz einer Klasse weiß intern, welche Methoden zu ihr gehören. Wenn ich jetzt die Zeichenroutine des Grafikobjekts aufrufe, wird immer die richtige Zeichenroutine der Instanz aufgerufen, sofern vorhanden. Da ich oben sowohl für Kreis als auch für Rechteck eine Zeichenroutine habe, wird die allgemeine Zeichenroutine mit dem MessageBeep nur via inherited aufgerufen, aber nie direkt.

Code:
  for I := 0 to 9 do
    Grafiken[I].Zeichnen;

Wenn ich fertig bin, muß ich die Instanzen der Klassen wieder zerstören, da diese ja (per constructor) dynamisch Speicher ausgefaßt haben. Das Schlüsselwort lautet dann destructor, dort kannst Du noch ein paar Sachen machen, z.B. weitere interne dynamische Sachen freigeben. Der Destructor Free ist übrigens in Delphi implizit vorhanden, weil Du das Schlüsselwort class verwendet hast.

Code:
  for I := 0 to 9 do
    Grafiken[I].Free;

Sicherheit + Gültigkeit in Klassen, Delphi-spezifisch

private: Diese Eigenschaften und Methoden sind nur innerhalb der Klasse bekannt.

protected: Diese Eigenschaften und Methoden sind auch in allen abgeleiteten Klassen bekannt (bei der Ausprogrammierung der Klassenmethoden), aber nicht nach außen (aus dem Hauptcode Deiner Anwendung).

public: Diese Sachen sind auch nach außen bekannt (sichtbar).

published: Diese Eigenschaften sind nicht nur aus der Anwendung heraus erreichbar, sondern Du siehst sie auch im Delphi-Objektinspektor, falls es sich bei der Klasse um eine Komponente handelt.

O Love

------------------
"I will not abide disobedience!"
 
Thema:

Delphi -- prozedurale Varianlen???

ANGEBOTE & SPONSOREN

https://www.mofapower.de/

Statistik des Forums

Themen
213.181
Beiträge
1.579.177
Mitglieder
55.880
Neuestes Mitglied
Hahn
Oben