Funktionspointer fuer Property?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Funktionspointer fuer Property?

Beitrag von Eclipticon »

Hi,

ich muss fuer ein Projekt eine Reihe von properties eines Objekts immer nach dem gleichen Schema abfragen. Aus Gruenden der Wartbarkeit des Codes wuerde ich gern diese fast identischen, laengeren Codebloecke gern in eine einzige Funktion auslagern.

Voraussetzung ist, dass ich auf diese Property in der Funktion weiter lesend und schreibend zugreifen kann (die dazugehoerigen methoden sind virtual). Ich muesste also nicht nur einen Wert sondern irgendwie die Adresse der property der Funktion als Parameter uebergeben ... geht das?

Vielen Dank :-)

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Funktionspointer fuer Property?

Beitrag von MAC »

ich hab zwar keihne ahnung, :)

aber was spricht gegen die normale benutzung von pointern.

Code: Alles auswählen

private
    fa:real;
  public
    property a:real read fa write fa;
  end;   
 
function machdas(a:^real);
begin
a^ := 11+random;
end; 
 
procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Caption := floattoStr(machdas(@Form1.a));
end;
sonnst gib mal ein bisschen code.

Code: Alles auswählen

Signatur := nil;

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Funktionspointer fuer Property?

Beitrag von Socke »

Wenn du viele "Eigenschaften" des selben Typs hast, kannst du auch indizierte Eigenschaften verwenden:

Code: Alles auswählen

myarr: array[0..19] of Integer;
// ...
property IntProp[Index: Longint]: Integer read GetIntProp write SetIntProp;
property abc: Integer index 5 read GetIntProp write SetIntProp;  // ist gleich IntProp[5]
// ...
procedure TMyclass.GetIntProp(Index: Longint; const AValue: Integer);
begin
  // z.B. auf einen Array zugreifen
  myarr[Index] := AValue;
end;
 
function TMyclass.SetIntProp(Index: Longint): Integer;
begin
  Result := myarr[Index]
end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Funktionspointer fuer Property?

Beitrag von Eclipticon »

Hi MAC,

mein Code sieht etwa so aus:

Code: Alles auswählen

type PtrDouble: ^double;
 
function TMainForm.TestBoundaries(AFunction: PtrDouble; StartValue: double; Increment: double; MaxIterations: integer): double;
var
  i: integer;
begin
  i    := 0;
  AFunction^ := StartValue;
  while (i < MaxIterations) do
  begin
      try
        Inc(i);
        Application.ProcessMessages;
        AFunction^ := AFunction^ + Increment;
      except
        Increment := Increment * 0.5;
      end;
  end;
  Result := AFunction^;
end;
 
procedure TMainForm.Something;
begin
   // ...
   Test := TestBoundaries(@ADevice.CoordinateZ, 0.0, 50.0, 50);
   // ....
end;
Nur zum Verstaendnis des Codes: Ich moechte die maximale CoordinateZ eines Geraets abfragen, ADevice.SetCoordinateZ loest eine Exception aus, wenn der uebergebene Wert nicht mehr gueltig ist.

Mein Compiler beschwert sich jetzt ueber "@ADevice.CoordinateZ": Variable identifier expected.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6773
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Funktionspointer fuer Property?

Beitrag von af0815 »

Eclipticon hat geschrieben:Mein Compiler beschwert sich jetzt ueber "@ADevice.CoordinateZ": Variable identifier expected.
In dem Code den du gepostet hast, ist ADevice nicht definiert, und auch keine deklaration von CoordinateZ ersichtlich.

Er erwartet dort eine Variable, du gibst ihm aber ein Property. Umgekehrt betrachtet, warum übergibst du ihm kein Objekt und rufst in der Schleife das Property des Objektes auf ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Funktionspointer fuer Property?

Beitrag von mschnell »

Willst Du da wirklich eine Funktion als untypisierten Pointer übergeben (und dann vermutlich nachher eine Typumwandlung machen) ?

In ANSI-C geht so was in Spezialfällen gerade noch durch in Pascal ist das ganz schlechter Stil da hochgradig Absturz-gefährdet.

Das kann man mit einer vernünftigen Objekt-Struktur bestimmt auch sauber lösen.

-Michael

Keifor
Beiträge: 31
Registriert: Sa 28. Aug 2010, 15:15
OS, Lazarus, FPC: pc-linux-gnu - Funtoo stable, L trunk, FPC trunk
CPU-Target: i686/x86_64

Re: Funktionspointer fuer Property?

Beitrag von Keifor »

Hi,

1. Mal zur Korrektur: Properties als Adresse/Zeiger übergeben zu wollen ist einfach nur falsch.. Properties sind syntaktische Mittel um Zugriffe auf Attribute/Methoden einzuschränken/zu erlauben (und noch ein paar Sachen mehr). Daher auch der Fehler "Variable identifier expected" -> Property ist keine Variable/Funktion/etc. im engeren Sinne.

Aus der Dokumentation: http://www.freepascal.org/docs-html/ref ... 870006.4.1" onclick="window.open(this.href);return false;
".. properties cannot be passed as var arguments to a function or procedure, since there is no known address of the property (at least, not always)"

@MAC:
MAC hat geschrieben:aber was spricht gegen die normale benutzung von pointern.
Die Art wie du es machst, gibt einen Zeiger auf den "Wert" des Properties zurück. :wink:

Das ähnlicher Code nicht bei Ecliptic läuft kann an unterschiedlichen Compiler Versionen oder Modes (Delphi/ObjFPC unterscheiden sich stärker wenn es um Pointer geht) liegen.

2. Wie meine Vorredner schon angemerkt habe. Es gibt andere/sichere/bessere Möglichkeiten.
Die anfängliche Frage klingt für mich so: "Ich möchte auf mehreren Objekten einer/mehrerer Klassen eine Funktion nutzen."
Klingt nach einem typischen Fall von OOP..

Wenn alle "Devices" von einem Typen TDevice abgeleitet sind der das entsprechende Propertie tägt -> Objekt übergeben und auf Property
zugreifen. (von diesem Fall geh ich mal aus, wenn die dahinter liegenden Methoden Virtuell sind, würde es keinen Sinn machen das Property erst in abgeleiteten Klassen einzuführen)

Wenn die Klassen unterschiedlich sind, die Properties unterschiedlich benannt etc.. dann gibt es auch wieder einfache Mechanismen, wie das abfragen der Klasse und entsprechenden Zugriff...

</senf>

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Funktionspointer fuer Property?

Beitrag von mschnell »

Keifor hat geschrieben:Wenn die Klassen unterschiedlich sind, die Properties unterschiedlich benannt etc.. dann gibt es auch wieder einfache Mechanismen, wie das abfragen der Klasse und entsprechenden Zugriff...
Genau. er sollte sich in "Vererbung" und "Polymorphismus" einlesen und feststellen, dass der Typ einer Property eine Klasse eines Vorgängertyps der Instanz sein kann, die man der Property zuordnet und man dann mit der Property eine virtuelle Funktion der Basis-Klasse aufrufen kann, die von der aktuellen Klasse überschrieben wurde und somit immer die korrekte Funktion verwendet wird, ohne dass die Klasse, die die Property hat und die Funktion aufruft, das unterscheiden muss.

-Michael

u-boot
Beiträge: 308
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Re: Funktionspointer fuer Property?

Beitrag von u-boot »

hm Property als Parameter

Das Thema hat mich sofort an folgendes Problem erinnert:

http://www.lazarusforum.de/viewtopic.php?f=18&t=4599

Code: Alles auswählen

procedure TForm1.StringGrid1SelectEditor(Sender: TObject; aCol, aRow: Integer;
  var Editor: TWinControl);
Editor sollte eigentlich ein Parameter sein. Wem eine gute Lösung einfällt wie man das besser gestaltet, darf gerne einen Patch schreiben.
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

Antworten