AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Zeiger als Parameter eines generischen Typs, TRecordList
Thema durchsuchen
Ansicht
Themen-Optionen

Zeiger als Parameter eines generischen Typs, TRecordList

Ein Thema von Panthrax · begonnen am 30. Mär 2009 · letzter Beitrag vom 2. Apr 2009
Antwort Antwort
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#1

Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 30. Mär 2009, 09:44
Ich überlege, wie weit mir Generika helfen, meine Klassen zu verbessern. In folgendem Fall möchte ich meine Klasse TRecordList als generische Klasse implementieren. TRecordList verwaltet eine Liste Records. P soll der Typparameter sein, z.B. PMyRecord = ^TMyRecord. Problematisch sind die Zuweisungen der Zeiger aus der gekapselten Liste (property List: TList read FList) an Result: P (in GetItem) und von Value: P (in SetItem):
Delphi-Quellcode:
function TRecordList

.GetItem(const Index: Integer): P;
begin
  Pointer(Result):=List[Index];
end;

procedure TRecordList

.SetItem(const Index: Integer; const Value: P);
begin
  List[Index]:=Value;
end;
Problematisch ist, dass ich keine Möglichkeit kenne, die möglichen Typparameterwerte auf Zeiger einzugrenzen. Entprechend muss der Compiler die Zuweisungen bemängeln.

Kann man die Werte irgendwie eingrenzen? Oder, wie kann man Zuweisungen zwischen einem Zeiger und einer Variable "unbekannten Typs" (aber es soll ein Zeiger sein) durchführen?

Hier noch einmal der Quelltext im Zusammenhang, so wie ich mir das vorstelle (auf das Nötige gekürzt). Leider dürfte das in den Methoden GetItem, SetItem, GetRecordSize nicht funktionieren, wenn ich mir vorstelle, dass P eben nicht nur für einen Zeiger stehen kann, sondern auch für eine Zahl, einen String, eine Klasse, eine Schnittstelle,... ("Dürfte" deshalb, weil ich es selbst nicht probieren kann.)
Delphi-Quellcode:
unit RecordList;

interface

uses
  Classes;

type
  TRecordList

 = class
    strict private
    FList: TList;

    strict protected
    property List: TList read FList;

    function GetItem(const Index: Integer): P;
    function GetRecordSize: Integer;
    procedure SetItem(const Index: Integer; const Value: P);

    public
    property Items[const Index: Integer]: P read GetItem write SetItem; default;
    property RecordSize: Integer read GetRecordSize;

    constructor Create;
    destructor Destroy; override;
  end;

  TMyRecord = record
    { ... }
  end;
  PMyRecord = ^TMyRecord;
  TMyRecordList = TRecordList<PMyRecord>;

implementation

{ TRecordList

}


constructor TRecordList

.Create;
begin
  inherited Create;
  FList:=TList.Create;
end;

destructor TRecordList

.Destroy;
begin
  List.Free;
  inherited;
end;

function TRecordList

.GetItem(const Index: Integer): P;
begin
  Pointer(Result):=List[Index];
end;

function TRecordList

.GetRecordSize: Integer;
begin
  Result:=SizeOf(P^);
end;

procedure TRecordList

.SetItem(const Index: Integer; const Value: P);
begin
  List[Index]:=Value;
end;

end.
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#2

Re: Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 2. Apr 2009, 12:32
Heißt das, es gibt keine Lösung, oder es weiß keiner eine Lösung?
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#3

Re: Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 2. Apr 2009, 12:37
Warum müssen es Records sein?
Nimm doch TObjectList als Ausgangspunkt.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#4

Re: Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 2. Apr 2009, 12:38
Wäre es nicht sinnvoller, als Typparameter den eigentlichen Record zu übergeben statt einem Pointer darauf?
  Mit Zitat antworten Zitat
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#5

Re: Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 2. Apr 2009, 12:56
Zitat von shmia:
Warum müssen es Records sein?
Nimm doch TObjectList als Ausgangspunkt.
Records sind völlig ausreichend und haben den Geschwindigkeitsvorteil ggü. Objekten -- New und Dispose vs. Create und Destroy. Es geht auch darum, die Daten über das Netzwerk zu schicken -- Stream.Write(RecPtr^,SizeOf(TRecord)) vs. eigene Schreibmethode pro Typ.

Zitat von jfheins:
Wäre es nicht sinnvoller, als Typparameter den eigentlichen Record zu übergeben statt einen Pointer darauf?
Nein, denn dann würde Items[I].RecordFeld := Wert nicht mehr den Record in der Liste ändern, sondern nur eine Kopie. Außerdem lässt sich so einfach TList nutzen.
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#6

Re: Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 2. Apr 2009, 13:55
Zitat von Panthrax:
Zitat von jfheins:
Wäre es nicht sinnvoller, als Typparameter den eigentlichen Record zu übergeben statt einen Pointer darauf?
Nein, denn dann würde Items[I].RecordFeld := Wert nicht mehr den Record in der Liste ändern, sondern nur eine Kopie. Außerdem lässt sich so einfach TList nutzen.
So hat er das wohl nicht gemeint.

Geht das hier?
Delphi-Quellcode:
type TRecordList<T> = class(T:record)
  type PItemType = ^T;
  ...
  function GetItem(const Index: Integer): PItemType;
end;
Oder das?
Delphi-Quellcode:
type TRecordList<T> = class(T:record)
  ...
  function GetItem(const Index: Integer): ^T;
end;
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#7

Re: Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 2. Apr 2009, 15:46
Ok, ich denke, so etwas müsste die Lösung sein:
Delphi-Quellcode:
type
  TRecordList<T: record> = class
    type
      TRecPtr = ^T;
    { ... }
  end;
Vielen Dank für den Hinweis! An diese Möglichkeit hatte ich nicht gedacht.

Leider funktioniert das aber nicht (Quelltext siehe unten):
Zitat von Compiler (Delphi 2009, Update 1 und 2):
[DCC Fataler Fehler] RecordList.pas(72): F2084 Interner Fehler: AV21B654E9-R00000000-0
Der Compilerlauf ist fehlerfrei, wenn GetItem und SetItem nicht deklariert sind. Überhaupt, es scheint mir es leicht zu sein, den Compiler zum Absturz zu bringen. Tja, was tun?

Delphi-Quellcode:
unit RecordList;

interface

uses
  Classes;

type
  TRecordList<T> = class
    public
    type
      TRecPtr = ^T;

    strict private
    FList: TList;

    strict protected
    property List: TList read FList;

    function GetItem(const Index: Integer): TRecPtr;
    function GetRecordSize: Integer;
    procedure SetItem(const Index: Integer; const Value: TRecPtr);

    public
// property Items[const Index: Integer]: TRecPtr read GetItem write SetItem; default;
    property RecordSize: Integer read GetRecordSize;

    constructor Create;
    destructor Destroy; override;
  end;

  TMyRecord = record
    { ... }
  end;

  PMyRecord = ^TMyRecord;
  TMyRecordList = TRecordList<PMyRecord>;

implementation

{ TRecordList<T> }

constructor TRecordList<T>.Create;
begin
  inherited Create;
  FList:=TList.Create;
end;

destructor TRecordList<T>.Destroy;
begin
  List.Free;
  inherited;
end;

function TRecordList<T>.GetItem(const Index: Integer): TRecPtr;
begin
// Result := List[Index];
end;

function TRecordList<T>.GetRecordSize: Integer;
begin
  Result := SizeOf(T);
end;

procedure TRecordList<T>.SetItem(const Index: Integer; const Value: TRecPtr);
begin
// List[Index] := Value;
end;

end.
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#8

Re: Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 2. Apr 2009, 15:59
http://qc.embarcadero.com/wc/qcmain.aspx?d=66577
  Mit Zitat antworten Zitat
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#9

Re: Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 2. Apr 2009, 16:11
Zitat von jfheins:
http://qc.embarcadero.com/wc/qcmain.aspx?d=66577
Ganz genau!

Ärgerlich, auf QC ergießen sich die Fehlermeldungen über den Compiler...
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  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 15:13 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