AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Ein Record als Property in einer Klasse

Ein Thema von Jelly · begonnen am 12. Jan 2004 · letzter Beitrag vom 12. Jan 2004
Antwort Antwort
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#1

Ein Record als Property in einer Klasse

  Alt 12. Jan 2004, 09:50
Hallo zusammen,

hab ein skurieles Problem. Folgender Code:

Delphi-Quellcode:
type
  TVector = record
               x, y, z : double ;
            end ;

  TProbe = class
  private
    Fr0: TVector;
    Fr1: TVector;
    procedure Setr0(const Value: TVector);
    procedure Setr1(const Value: TVector);
  public
    property r0 : TVector read Fr0 write Setr0 ;
    property r1 : TVector read Fr1 write Setr1 ;
    constructor Create ;
  end ;

var
 Probe : TProbe ;
Probier ich jetzt mittels Probe.r0.x := 3 ; einen Wert zuzuweisen, krieg ich ne Fehlermeldung beim Kompilieren:
Zitat von Delphi Compiler:
Left side cannot be assigned to
Woran kann das liegen. Lesender Zugriff funktioniert hingegen. Kann man keine Records als Eigenschaften deklarieren etwa?

Wer weiß da Rat?

Gruß,
Tom
  Mit Zitat antworten Zitat
Benutzerbild von Leuselator
Leuselator

Registriert seit: 18. Mär 2003
Ort: Berlin
589 Beiträge
 
Delphi 8 Architect
 
#2

Re: Ein Record als Property in einer Klasse

  Alt 12. Jan 2004, 09:55
Das ist der Sinn von Properties: die Objektdaten vor direktem Zugriff von aussen zu schützen! Du müßtest schon einen kompletten Record übergeben/zuweisen - dann klappt es:
Delphi-Quellcode:
var TempVector : TVector;
begin
  TempVector := Probe.r0;
  TempVector.x := 3;
  Probe.r0 := TempVector;
end;
Tim Leuschner
Programmierer = moderner Sysiphos: stets wenn er meint, den Stein seiner Dummheit auf den Berg des Wissens gewuchtet zu haben, erblickt er einen völlig neuen Aspekt und der Dummfels poltert mit Getöse zurück ins Tal der Unwissenheit...
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#3

Re: Ein Record als Property in einer Klasse

  Alt 12. Jan 2004, 09:59
Zitat von Leuselator:
Das ist der Sinn von Properties: die Objektdaten vor direktem Zugriff von aussen zu schützen!
Komisch. Ein Record ist doch kein Objekt? Versteh diese Logik nicht ganz von Borland, zumal das Lesen ja funktioniert. Mach ichs halt über Umweg. Danke für deine rasche Stellungsnahme.

Gruss,
Tom
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#4

Re: Ein Record als Property in einer Klasse

  Alt 12. Jan 2004, 11:14
Hallo Jelly,

es geht bei Diesem Ansatz im Wesentlichen um die Einhaltung von gültigen Invarianten, die eine logiklose Struktur, wie ein Record, nicht gewährleisten kann.
Darüber hinaus sollte die Schnittstelle (hier: zugänglich durch Properties) nichts über die konkrete Implementierung aussagen. Tatsächlich ist es nicht notwendig, dass eine Klasse eine Exemplarvariable für den Strukturierten Datentyp besitzt.

Im folgenden Beispiel beschreibe ich eine Klasse zur Darstellung eines Quadrats, die eine Eigenschaft Bounds besitzt. Sie gibt Auskünft über das kleinste umschließende Rechteck des dargestellten Quadrats. Selbstverständlich entspricht der Wert beim lesenden Zugriff immer dem Quadrat selbst, beim schreiben jedoch, sollte das Quadrat angepasst werden (Setzen der Quadratkantenlänge auf die kleiner der beiden Seiten des umschließenden Rechtecks). Es ist offensichtlich unnötig, die beiden Seitenlängen des Rechtecks zu speichern.
Folgende Besonderheit ist in diesem Beispiel vorgesehen: Sollten beide Längen des umschließenden Rechtecks negativ sein, werden die beiden Längen invertiert betrachtet (andernfalls macht das Bsp wg der Invarianten keinen Sinn )
Delphi-Quellcode:
type
  TMySquare = class
  private
    FLen: Double;
    function GetBounds: TPoint;
    procedure SetBounds(const AValue: TPoint);
  public
    property Bounds: TPoint
      read GetBounds
      write SetBounds;
  end;

function TMySqare.GetBounds: TPoint;
begin
  Result:= Point(FLen, FLen);
end;

procedure TMySquare.SetBounds(const AValue: TPoint);
begin
  with AValue do
  begin
    // only same sign and not null
    if Math.Sign(X)*Math.Sign(Y)<>1 then
      raise EInvalidArgument...
  
    Self.FLen:= Min(Abs(X), Abs(Y));
  end;
end;
An diesem Beispiel kann nun gezeigt werden, dass Zugriffe auf Felder des Records nicht eindeutig realisiert werden können:
Delphi-Quellcode:
mySquare.Bounds:= Point(10, 10); //FLen=10
mySquare.Bounds:= Point(-5, -2); //FLen=2
myPoint:= mySquare.Bounds; // myPoint=(2, 2)
mySquare.Bounds.X:= 1; // ???
Solltest Du hingegen einen Zugriff der Art
mySquare.Bounds.X:= myValue; benötigen, kannst Du dies durch eine Hilfsklasse, die von TPersistent abgeleitet wird, realisieren. Die Eigenschaft Font der Klasse TControl ist bspw so realisiert.
gruß, choose
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#5

Re: Ein Record als Property in einer Klasse

  Alt 12. Jan 2004, 11:20
Danke choose für die ausführlich Schilderung. Habs jetzt kapiert.

Das mit TPersistent war mir bekannt. Mir ging es lediglich um die Record Datenstruktur, was mich anfanglich doch sehr verwundert hat, warum das Schreiben fehlschlug. An deinem Beispiel ist das aber klar nachzuvollziehen.

Übrigens ist nicht mal die Klasse TPersistent nötig. Eine einfach TClass reicht schon vollkommen aus.

Gruß,
Tom
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#6

Re: Ein Record als Property in einer Klasse

  Alt 12. Jan 2004, 11:28
Hallo Jelly,

schön, dass ich Dir helfen konnte. Für Änderungen zur Laufzeit ist tatsächlich eine beliebige Klasse ausreichend, um einzelne Felder ändern zu können. Zur Designzeit müssen Properties allerdings als published deklariert und die aggregierten Klassen zusätzlich mit RTTI (Reflektions-/Introspektionscode) kompiliert worden sein, damit der OI mit ihnen arbeiten kann. Diese Forderung erfüllst Du dabei entwerder mit der lokalen Kompileroption {$M+} oder durch Erben von der Klasse TPersistent.
gruß, choose
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:35 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