![]() |
Zeiger als Parameter eines generischen Typs, TRecordList
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:
Problematisch ist, dass ich keine Möglichkeit kenne, die möglichen Typparameterwerte auf Zeiger einzugrenzen. Entprechend muss der Compiler die Zuweisungen bemängeln.
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; 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. |
Re: Zeiger als Parameter eines generischen Typs, TRecordList
Heißt das, es gibt keine Lösung, oder es weiß keiner eine Lösung? :gruebel:
|
Re: Zeiger als Parameter eines generischen Typs, TRecordList
Warum müssen es Records sein?
Nimm doch TObjectList als Ausgangspunkt. |
Re: Zeiger als Parameter eines generischen Typs, TRecordList
Wäre es nicht sinnvoller, als Typparameter den eigentlichen Record zu übergeben statt einem Pointer darauf?
|
Re: Zeiger als Parameter eines generischen Typs, TRecordList
Zitat:
Zitat:
|
Re: Zeiger als Parameter eines generischen Typs, TRecordList
Zitat:
Geht das hier?
Delphi-Quellcode:
Oder das?
type TRecordList<T> = class(T:record)
type PItemType = ^T; ... function GetItem(const Index: Integer): PItemType; end;
Delphi-Quellcode:
type TRecordList<T> = class(T:record)
... function GetItem(const Index: Integer): ^T; end; |
Re: Zeiger als Parameter eines generischen Typs, TRecordList
Ok, ich denke, so etwas müsste die Lösung sein:
Delphi-Quellcode:
Vielen Dank für den Hinweis! An diese Möglichkeit hatte ich nicht gedacht.
type
TRecordList<T: record> = class type TRecPtr = ^T; { ... } end; Leider funktioniert das aber nicht (Quelltext siehe unten): Zitat:
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. |
Re: Zeiger als Parameter eines generischen Typs, TRecordList
|
Re: Zeiger als Parameter eines generischen Typs, TRecordList
Zitat:
Ärgerlich, auf QC ergießen sich die Fehlermeldungen über den Compiler... :wall: :roll: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:30 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz