Zugrif auf Element von Record eines Objectes

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1629
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Zugrif auf Element von Record eines Objectes

Beitrag von corpsman »

Hossa,
sorry für den fürchterlichen Titel

Worum es geht, ich hab die unten stehende Deklaration :

Code: Alles auswählen

 
type
  r = record
    e1: integer;
    e2: integer;
  end;
 
  b = class
  private
    fe: array of r;
    function gete(index: integer): r;
    procedure Sete(index: integer; AValue: R);
  public
    property e[index: integer]: r read gete write sete;
  end; 
 
Wenn ich nun eine Instant von B mache und dann auf e1 zugreifen will geht das nur indirekt

Code: Alles auswählen

 
var c:B;
    rr:r;
begin
  c.e[0].e1 := 1; // Hier kommt ein Fehler, dass er nicht zuweisen kann
  r := c.e[0]; // Das ist quasi der "Workaround"
  r.e1 := 1;// Das ist quasi der "Workaround"
  c.e[0] :=r;// Das ist quasi der "Workaround"
  if (c.e[0].e1 = 0) then begin // Das Geht
  end;
end;
 
Gibt es einen Trick mit dem ich es hinbekomme, dass er die Zuweisung " c.e[0].e1 := 1;" macht. Oder muss man immer den "Workaround" nehmen ?
Im Referenzmanual konnte ich da so direkt nichts finden..
--
Just try it

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Zugrif auf Element von Record eines Objectes

Beitrag von Michl »

Ein Direktzugriff wäre möglich mit

Code: Alles auswählen

  with c.e[0] do e1:=1; 
... ist aber als deprecated zu betrachten lt. http://bugs.freepascal.org/view.php?id=15273

Ist auch in deinem Fall bug-anfällig, da eine mögliche Bereichsprüfung deiner Sete-Methode dann nicht stattfindet!

Daher wäre der von dir gepostete Code das einzig richtige Vorgehen!

(Zumindest wenn du rr statt r schreibst...

Code: Alles auswählen

  rr := c.e[0]; // Das ist quasi der "Workaround"
  rr.e1 := 1;// Das ist quasi der "Workaround"
  c.e[0] := rr;// Das ist quasi der "Workaround"
) :roll:

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Frank Ranis
Beiträge: 210
Registriert: Do 24. Jan 2013, 21:22

Re: Zugrif auf Element von Record eines Objectes

Beitrag von Frank Ranis »

Hallo corpsman,

muß man das Objekt nicht erst mal erzeugen, bevor man es benutzt?
Oder zumindest ein bereits vorhandenes Objekt zuweisen.

Code: Alles auswählen

var c:B;
    rr:r;
begin
  c:=b.create; // Hier erzeugen
  // oder vorhandenes Objekt vom Typ b benutzen
  c:=vorhandenes_b_Objekt;
 
 
  c.e[0].e1 := 1; // Hier kommt ein Fehler, dass er nicht zuweisen kann
  r := c.e[0]; // Das ist quasi der "Workaround"
  r.e1 := 1;// Das ist quasi der "Workaround"
  c.e[0] :=r;// Das ist quasi der "Workaround"
  if (c.e[0].e1 = 0) then begin // Das Geht
  end;
 
  c.free; //  wieder freigeben , wenn man es nicht mehr braucht
end;

Gruß

Frank
www.flz-vortex.de

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2822
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Zugrif auf Element von Record eines Objectes

Beitrag von m.fuchs »

Frank Ranis hat geschrieben:muß man das Objekt nicht erst mal erzeugen, bevor man es benutzt?
Oder zumindest ein bereits vorhandenes Objekt zuweisen.
Das ändert aber nichts am Fehler, denn da beschwert sich schon der Compiler. Eine Zugriffsverletzung wegen nicht initialisiertem Objekt ist in diesem Fall nicht das Problem.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2822
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Zugrif auf Element von Record eines Objectes

Beitrag von m.fuchs »

Hallo corpsman,

an der Index-Property liegt es schon mal nicht, dieser Code hier hat das gleiche Problem:

Code: Alles auswählen

type
  r = record
    e1: integer;
    e2: integer;
  end;
 
  b = class
    private
      Fx: r;
    public
      property x: r read Fx write Fx;
  end;
 
var
  c:b;
 
begin
  c := b.Create;
  c.x.e1 := 0;
  c.Free;
end.
Ich vermute mal das ist das gleiche Problem wie bei Properties als var-Parameter, auch das ist ja nicht möglich. Du greifst mit einer Property nicht direkt auf den Speicher des (möglicherweise) dahinterliegenden Feldes zu.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2822
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Zugrif auf Element von Record eines Objectes

Beitrag von m.fuchs »

Was übrigens eine Alternative wäre, wenn du Properties auf die einzelnen Felder eines Records zeigen lässt:

Code: Alles auswählen

type
  TMyRecord = record
    I1, I2: Integer;
  end;
 
  TMyClass = class(TObject)
    private
      Records: array of TMyRecord;
      function GetI1(Index: Integer): Integer;
      function GetI2(Index: Integer): Integer;
      procedure SetI1(Index: Integer; AValue: Integer);
      procedure SetI2(Index: Integer; AValue: Integer);
    public
      property I1[Index: Integer]: Integer read GetI1 write SetI1;
      property I2[Index: Integer]: Integer read GetI2 write SetI2;
    public
      constructor Create;
  end;
 
function TMyClass.GetI1(Index: Integer): Integer;
begin
  Result := Records[Index].I1;
end;
 
function TMyClass.GetI2(Index: Integer): Integer;
begin
  Result := Records[Index].I2;
end;
 
procedure TMyClass.SetI1(Index: Integer; AValue: Integer);
begin
  Records[Index].I1 := AValue;
end;
 
procedure TMyClass.SetI2(Index: Integer; AValue: Integer);
begin
  Records[Index].I2 := AValue;
end;
 
constructor TMyClass.Create;
begin
  inherited Create;
  SetLength(Records, 10);
end;
 
 
var
  MyClass: TMyClass;
 
begin
  MyClass := TMyClass.Create;
  MyClass.I1[4] := 7;
  MyClass.Free;
end.
Ist aber etwas umständlich wenn man einen Record mit vielen Feldern hat.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Zugrif auf Element von Record eines Objectes

Beitrag von Michl »

m.fuchs hat geschrieben:Hallo corpsman,

an der Index-Property liegt es schon mal nicht, dieser Code hier hat das gleiche Problem:

Code: Alles auswählen

type
  r = record
    e1: integer;
    e2: integer;
  end;
...
Wie ich schon oben schrieb, wurde dieses Vorgehen schon im Bug-Tracker diskutiert und ein Direktzugriff als nicht erwünscht betrachtet!!!
http://bugs.freepascal.org/view.php?id=15273
bzw. Diskussion zum gleichen Problem http://bugs.freepascal.org/view.php?id=14534

Ein Direktzugriff auf die Record-Werte ist noch mit dem "with"-Statement möglich

Außerdem glaube ich, dass Corpsmann (ausgehend von seinen Postings) durchaus weiss, dass ein Zugriff erst erfolgen kann, wenn Klasse.create ausgeführt wurde (ist eher als Pseudo-code zu lesen) und es geht ihm hier um das Prinzip!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1629
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Zugrif auf Element von Record eines Objectes

Beitrag von corpsman »

Danke Michl für die Verteidigung, selbstredend ist mir klar das ein Object vorher instanziiert werden muss *g*.

Was den "With" Operator angeht so verwende ich diesen Grundsätzlich nicht. Damals unter Delphi war dieser "Schick". Sobald man aber mit $mode Objfpc kompiliert knallts an allen Ecken, das musste ich bitter Lernen. Auch finde ich nicht, dass es die Lesbarkeit erhöht. FPC finde ich gerade toll, weil es in vieler Hinsicht zum "sauberen" Programmieren erzieht. Das "With" konstrukt wirkt hier Kontraproduktiv.

Die Variante von m.fuchs scheint damit leider die einzige Alternative zu sein. Da werde ich bei meinem "Alten" komplizierteren Verdfahren bleiben.

Vielen Dank für eure Meinung.

Gruß

Corpsman
--
Just try it

Frank Ranis
Beiträge: 210
Registriert: Do 24. Jan 2013, 21:22

Re: Zugrif auf Element von Record eines Objectes

Beitrag von Frank Ranis »

Hallo corpsman,

ich wollte dir auf keinem Fall auf die Füße treten.
Beim durchlesen ist mir das nur aufgefallen, hätte ja eine möglicher Ursache sein können.

>>
Was den "With" Operator angeht so verwende ich diesen Grundsätzlich nicht.
<<

Mit dem With sprichst Du mir aus der Seele, wenn man größere Code-Brocken hat (vor allen mit viel With drinn) , weiss man nach kurzer Zeit nicht mehr wo oben und unten ist und welches Objekt nun zu welchem gehört.

Gruß

Frank
www.flz-vortex.de

Antworten