Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Generics in Record (https://www.delphipraxis.net/154240-generics-record.html)

Björn Ole 2. Sep 2010 12:44

Generics in Record
 
Hi,

ich beschäftige mich gerade etwas näher mit Generics und stehe vor einem Problem. Folgende Testklasse:
Delphi-Quellcode:
TRecObj<T> = class
type
  PRec = ^TRec;
  TRec = record
    ID: integer;
    Data: T;
  end;
private
  FRec: PRec;
public
  constructor Create(ID: integer; Data: T);
  destructor Destroy; reintroduce;
end;


constructor TRecObj<T>.Create(ID: integer; Data: T);
begin
  inherited Create;
  New(FRec);
  FRec.ID := ID;
  FRec.Data := Data; // schmeißt AV
end;

destructor TRecObj<T>.Destroy;
begin
  Dispose(FRec);
  inherited Destroy;
end;


myObj := TRecObj<string>.Create(-17, 'Hallo');
Das Record mag in diesem Beispiel nicht viel Sinn machen; ich möchte aber ein eigenes Listenobjekt programmieren, bei dem jedes Element aus so einem Record besteht.

Wenn ich mir jetzt ein neues TRecObj erstelle, bekomm ich eine AV (Read of address FFFFFFFB) bei der Zuweisung von Data. Benutze ich hier die Generics falsch? Warum funktioniert das so nicht?


Danke, Björn

mkinzler 2. Sep 2010 12:47

AW: Generics in Record
 
Warum legst du einen Zeiger auf die Struktur ab und nicht die Struktur selber?

Björn Ole 2. Sep 2010 13:48

AW: Generics in Record
 
In der Testklasse von oben funktioniert es, aber warum nicht mit einem Zeiger und New()?

Ich glaub ich hatte das Problem zu weit vereinfacht.
Wie kann ich das nun auf meine Liste anwenden?

Ausschnitt:
Delphi-Quellcode:
TMyList<T> = class
  type
    PRec = ^TRec;
    TRec = record
      ID: integer
      Data: T;
      Next: PRec;
    end;
  private
    FCount: integer;
    FFirst: PRec;
    FLast: PRec;
    {...}

mkinzler 2. Sep 2010 13:55

AW: Generics in Record
 
Versuch es mal mit Klassen. So scheint es zu gehen

Delphi-Quellcode:
unit GTU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

TRecObj<T> = class
type
  //PRec = ^TRec;
  TRec = class
    ID: integer;
    Data: T;
  end;
private
  FRec: TRec;
public
  constructor Create(ID: integer; Data: T);
  destructor Destroy; reintroduce;
end;

var
  Form1: TForm1;
  myObj: TRecObj<string>;

implementation

{$R *.dfm}

constructor TRecObj<T>.Create(ID: integer; Data: T);
begin
  inherited Create;
  FRec := TRec.Create;
  FRec.ID := ID;
  FRec.Data := Data; // schmeißt AV
end;

destructor TRecObj<T>.Destroy;
begin
  FRec.Destroy;
  inherited Destroy;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    myObj := TRecObj<string>.Create(-17, 'Hallo');
    Caption := myObj.FRec.Data;
end;

end.

Hawkeye219 2. Sep 2010 14:45

AW: Generics in Record
 
Hallo Björn,

versuche es einmal mit diesem Ansatz:
Delphi-Quellcode:
uses
  Generics.Collections;

type
  TRecord<T> = record
    ID: Integer;
    Data: T;
    constructor Init (const aID: Integer; const aData: T);
  end;

  TRecordList<T> = class (TList<TRecord<T>>)
    procedure AddItem (const aID: Integer; const aData: T);
  end;

constructor TRecord<T>.Init(const aID: Integer; const aData: T);
begin
  ID := aID;
  Data := aData;
end;

procedure TRecordList<T>.AddItem(const aID: Integer; const aData: T);
var
  R: TRecord<T>;
begin
  R.Init (aID, aData);
  Add(R);
end;

// Anwendung

var
  MyList: TRecordList<string>;
begin
  MyList := TRecordList<string>.Create;
  try
    MyList.AddItem (42, 'Hallo Welt');
    MyList.AddItem (0, 'EOF');
    ShowMessage (MyList[0].Data);
  finally
    MyList.Free;
  end;
end;
Oder habe ich etwas an deiner Problemstellung übersehen?

Falls die ID eine eindeutige Kennung des Records sein sollte, wäre vielleicht ein Blick auf TDictionary<TKey,TValue> sinnvoll.

Gruß Hawkeye

Björn Ole 2. Sep 2010 15:41

AW: Generics in Record
 
Danke für eure Tipps.

Habe es jetzt so gelöst:
Delphi-Quellcode:
type
  TItem<T> = class
  private
    FID: integer
    FData: T;
    FNext: TItem<T>;
  public
    constructor Create(AID: integer; AData: T);
    property ID: integer read FID;
    property Data: T read FData;
    property Next: TItem<T> read FNext write FNext;
  end;

  TItemList<T> = class
  type
    TListItem = TItem<T>;
  private
    FFirst: TListItem;
    FLast: TListItem;
    {...}
Damit kann ich bequem weiterarbeiten. :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:46 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