Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Probleme bei der Übergabe von Funktionen als Parameter
Christian213 - Mo 24.06.13 11:05
Titel: Probleme bei der Übergabe von Funktionen als Parameter
Hallo,
ich komme hier an einer Stelle nicht weiter. Ich verwende Lazarus in der aktuellen Version im Delphi-Modus.
Ich möchte gerne eine Prozedur mittels Übergabe einer Funktion als Parameter mehrfach verwenden.
Vom Prinzip her habe ich die Funktionsweise verstanden, leider scheint bei meiner Umsetzung noch ein Denkfehler drin zu sein:
Ich habe in der betroffenen Class eine Type-Definition:
type TFunctionParameter = function(const value1 : AnsiString; const value2 : AnsiString): boolean;
Diese wiederum benutze ich dann bei der Definition der Prozedur:
procedure Traverse(BaseDir: AnsiString; TargetDir: AnsiString; RelPath: AnsiString; _function: TFunctionParameter);
Innerhalb der Prozedur wird dann die übergebene Funktion _function mit Parametern aufgerufen.
Soweit, so gut.
Nun habe ich eine weitere Funktion, die ich als Funktions-Parameter übergeben möchte um damit die Prozedur "Traverse" aufzurufen:
function CopyIfNewer(Source: AnsiString; Target: AnsiString): boolean;
Wenn ich die Beispiele richtig verstanden habe, muss ich dazu nur den Funktionsnamen ohne Parameter übergeben:
Traverse('...', '...', '...', CopyIfNewer);
Hier meckert der Compiler dann aber:
Error: Incompatible type for arg no. 4: Got "TNovaUtils.TNovaUtils.CopyIfNewer(AnsiString,AnsiString):Boolean;", expected "TNovaUtils.<procedure variable type of function(const AnsiString,const AnsiString):Boolean;Register>"
Hint: Found declaration: TNovaUtils.Traverse(AnsiString,AnsiString,AnsiString,TFunctionParameter);
Meine Frage: Warum? Und wie macht man es richtig??
Danke! :-)
WasWeißDennIch - Mo 24.06.13 11:13
Und wenn Du die Parameter von CopyIfNewer auch als Konstanten deklarierst?
Gammatester - Mo 24.06.13 11:18
Du must die Parameter konsistent benutzen. Also
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TFunctionParameter = function(const value1 : AnsiString; const value2 : AnsiString): boolean; function CopyIfNewer(const Source: AnsiString; const Target: AnsiString): boolean;
type TFunctionParameter = function(value1 : AnsiString; value2 : AnsiString): boolean; function CopyIfNewer(Source: AnsiString; Target: AnsiString): boolean; |
Christian213 - Mo 24.06.13 11:26
Hallo,
Danke für die Antworten.
Das hatte ich auch schon ausprobiert, es ändert sich aber nicht wirklich viel dann:
Error: Incompatible type for arg no. 4: Got "TNovaUtils.TNovaUtils.CopyIfNewer(AnsiString,AnsiString):Boolean;", expected "TNovaUtils.<procedure variable type of function(AnsiString,AnsiString):Boolean;Register>"
Dieses "procedure variable type of function" und das ";Register" verwirren mich...
WasWeißDennIch - Mo 24.06.13 11:27
Kann es sein, dass CopyIfNewer eine Methode einer Klasse TNovaUtils ist?
Christian213 - Mo 24.06.13 11:33
WasWeißDennIch hat folgendes geschrieben : |
| Kann es sein, dass CopyIfNewer eine Methode einer Klasse TNovaUtils ist? |
Ja, ist es. Es sind alles "Mitglieder" dieser Klasse. Inklusive der Type-Definition.
Ich hatte das nur beim Copy&Paste weggeschnitten.
WasWeißDennIch - Mo 24.06.13 11:36
Dann versuch es mal mit
Delphi-Quelltext
1:
| type TFunctionParameter = function(const value1 : AnsiString; const value2 : AnsiString): boolean of object; |
Christian213 - Mo 24.06.13 11:41
WasWeißDennIch hat folgendes geschrieben : |
Dann versuch es mal mit
Delphi-Quelltext 1:
| type TFunctionParameter = function(const value1 : AnsiString; const value2 : AnsiString): boolean of object; | |
Damit geht's! Dankeschön! :-)
Das i-Tüpfelchen wäre nun, wenn Du mir noch kurz erklären könntest wieso hier ein "of object" hinter stehen muss.
WasWeißDennIch - Mo 24.06.13 11:44
Weil es sich um eine Methode handelt. Methoden gehören ja zu einem Objekt (genauer: einer Instanz), daher das "of object", während die sog. regulären Prozeduren/Funktionen für sich alleine stehen.
Christian213 - Mo 24.06.13 11:53
Okay, dann habe ich es verstanden, denke ich.
Danke für die tolle und schnelle Hilfe hier! :-)
Gruß,
Christian
jaenicke - Mo 24.06.13 13:52
Um mal den Hintergrund zu erklären:
Eine Methode besteht intern aus zwei Werten, dem Zeiger auf die Methode selbst (Code) und einem Zeiger auf das dazugehörige Objekt (Daten). Wenn die Methode aufgerufen wird, wird dieser zweite Zeiger für Zugriffe auf das Objekt benutzt, z.B. Zugriffe auf private Felder.
Eine Prozedur ohne Objekt ist ein einfacher Zeiger auf die Prozedur.
Und eine anonyme Methode beinhaltet zusätzlich zum Methodenzeiger noch Daten zum Scope zum Zeitpunkt des Erstellens der Methode, damit z.B. dort vorhandene lokale Variablen erst aufgeräumt werden, wenn auch die anonyme Methode samt Scope beendet ist.
OlafSt - Mo 24.06.13 17:22
jaenicke hat folgendes geschrieben : |
Um mal den Hintergrund zu erklären:
Eine Methode besteht intern aus zwei Werten, dem Zeiger auf die Methode selbst (Code) und einem Zeiger auf das dazugehörige Objekt (Daten). Wenn die Methode aufgerufen wird, wird dieser zweite Zeiger für Zugriffe auf das Objekt benutzt, z.B. Zugriffe auf private Felder.
|
Oder anders formuliert: Methodenaufrufe haben immer einen
versteckten ersten Parameter, der auf das Objekt selbst zeigt. Darum muß "of object" angegeben werden, damit der Compiler weiß "Aha, das ist ne Methode, ergo kommt da als erstes ein versteckter Parameter".
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!