![]() |
TList ableiten - Pointer -> eigener Pointertyp
Hi ihr,
gibt es eine einfache möglichkeit eine Klasse von TList abzuleiten, die sich nur darin unterscheidet, dass die einzelnen Elemente nicht ein einfacher Pointer sind, sondern ein Pointer auf einen bestimmten Typ? Genauer will ich eine TPunkteList = class(TList), wobei Items vom Typ PPunkt sein soll. Wie stell ich das am besten an? Geht das, ohne sämtliche Funktionen/Properties einzeln neu zu coden und auf den Typ anzupassen? |
Re: TList ableiten - Pointer -> eigener Pointertyp
Hallo StefanDP,
ich habe vor einer Weile TObjectList so abgeleitet, dass sie praktisch jeden Typ aufnehmen kann, ohne dass du lang rumfummeln musst. Die Loesung sind so genannte Templates, bei denen der Compiler einfach ein paar Extrarunden dreht ;) Das Ganze findest du hier: ![]() Und nachdem ich in Geberlaune bin, hier mal eine Unit fuer so ein Template:
Delphi-Quellcode:
Tja, und das war der Spass auch schon; fertig ist deine typisierte Liste :) (wenn ich nichts vergessen hab *g*)
unit Foobar;
interface uses Contnrs; type TMyItemClass = class(TObject) private fFoo: String; fBar: Integer; published property Foo: String read fFoo; property Bar: String read fBar; end; _LIST_ITEM_ = TMyItemClass; {$DEFINE TYPED_LIST_TEMPLATE} {$INCLUDE objlist_tmpl.pas} TMyTypedList = _LIST_; implementation {$INCLUDE objlist_tmpl.pas} end. Greetz alcaeus |
Re: TList ableiten - Pointer -> eigener Pointertyp
hat leider den Nachteil, dass man nicht zwei solcher Listen in einer Unit verwenden kann, da es da Namenskonflikte gibt.
Sollte erwähnt sein, wenn man es so hoch anpreist ;-) |
Re: TList ableiten - Pointer -> eigener Pointertyp
man kann sich übrigens die eine Schrubbelzeile :
{$DEFINE TYPED_LIST_TEMPLATE} sparen, wenn man die Unit auf folgende Art und Weise verwendet. Damit wird die Benutzung auch einfacher (und verständlicher) Werde sie aber aus den oben genannten Gründen dann doch nicht verwenden und mir schon gar nicht eine Bibliothek aufbauen oder so, ich stetze da mal auf die Livetempletes der IDE von 2006. Scheint mir zukunftssicherer. Wieder einen Nachmittag umsonst rumgefummelt :? bezieht sich darauf: ![]()
Delphi-Quellcode:
unit u_MemoList;
interface uses Sysutils, Classes, Contnrs, StdCtrls; type _TObjectListItem = TMemo; {$I templateTListU.pas} TMemoList = class(_TObjectList) end; implementation {$I templateTListU.pas} und die implementation
Delphi-Quellcode:
{$IFDEF DEVELOP_NEVER} // never define
unit templateTListU; interface uses Sysutils, Classes, Contnrs; type _TObjectListItem = TObject; {$ENDIF DEVELOP_NEVER} {$IFDEF _DECLARE_SECOND_PASS} {$DEFINE _SECOND_PASS} {$UNDEF _DECLARE_SECOND_PASS} {$ENDIF _DECLARE_SECOND_PASS} {$IFNDEF _SECOND_PASS} type _TObjectlist = class private protected fList: TObjectList; function GetItems(_Idx: integer): _TObjectListItem; function GetCount: integer; public constructor Create; destructor Destroy; override; function Add(_Item: _TObjectListItem): integer; function Remove(_Item: _TObjectListItem): integer; procedure Clear; property Items[_Idx: integer]: _TObjectListItem read GetItems; default; property Count: integer read GetCount; end; {$DEFINE _DECLARE_SECOND_PASS} {$ENDIF _SECOND_PASS} {$IFDEF DEVELOP_NEVER} implementation {$ENDIF DEVELOP_NEVER} {$IFDEF _SECOND_PASS} { _TObjectlist } constructor _TObjectlist.Create; begin inherited Create; fList := TObjectList.Create; end; destructor _TObjectlist.Destroy; begin fList.Free; inherited; end; function _TObjectlist.Add(_Item: _TObjectListItem): integer; begin Result := fList.Add(_Item); end; function _TObjectlist.Remove(_Item: _TObjectListItem): integer; begin Result := fList.Remove(_Item); end; procedure _TObjectlist.Clear; begin fList.clear; end; function _TObjectlist.GetItems(_Idx: integer): _TObjectListItem; begin Result := fList[_Idx] as _TObjectListItem; end; function _TObjectlist.GetCount: integer; begin Result := fList.Count; end; {$UNDEF _SECOND_PASS} {$ENDIF _Second_PASS} //{$WARNINGS off} |
Re: TList ableiten - Pointer -> eigener Pointertyp
ohne Template würde es so aussehen sofern man die Items nur über das Property Items abfragt:
Delphi-Quellcode:
TMyList = class(TList)
protected function GetNew(AIndex: Integer): TMyPointerType; procedure PutNew(AIndex: Integer; AItem: TMyPointerType); public property Items[Index: Integer]: TMyPointerType read GetNew write PutNew; default; end; [...] function TMyList.GetNew(AIndex: Integer): TMyPointerType; begin result := TMyPointerType(Get(AIndex)); end; procedure TMyList.PutNew(AIndex: Integer; AItem: TMyPointerType); begin Put(AIndex, AItem); end; |
Re: TList ableiten - Pointer -> eigener Pointertyp
Zitat:
Was die Templates betrifft: die LiveTemplates der IDE sind was total anderes. Wenn du sowas als Live-Template realisieren willst, hast du redundanten Code. Die Template-Datei wirfst du ins Lib-Verzeichnis rein, und gut is. Kein redundanter Code, Aenderungen werden in allen Projekten verfuegbar (sofern du das auch willst), usw. Nichtsdestotrotz haben die BDS-Templates und diese Templates eigentlich nichts gemeinsam. Dieses List-Template kann man am ehesten noch mit Generics aus .NET bzw. Java 1.5 vergleichen ;) Greetz alcaeus |
Re: TList ableiten - Pointer -> eigener Pointertyp
Liste der Anhänge anzeigen (Anzahl: 1)
irgendwie habe ich meinen Beitrag wieder editiert anstatt einen neuen Betrag zu erstellen.
(Könnte man die Buttons nicht irgendwie total grell bunt und verschiedenfarbig gestalten :-D ? ich hatte noch geschrieben: (hier stand noch) Zitat:
und nun der Text .. ----------------- also das mit den IFDEF Konstruktionen scheint eine kompliziertere Sache zu sein, als mein kleines Hirn überblicken kann. Es ist zwar so, dass meine Variante korrekt zu compilieren geht, aber da funktioniert erstaunlicherweise die Codevervollständigung nicht mehr ! :pale: Also das ist irgendwie unlogisch, verstehen tu ich es nicht, na egal. Man kann es sich aber dennoch vereinfach, wenn man IMMER
Delphi-Quellcode:
schreibt. Da muss man sich nicht soviel merken !
{$DEFINE TEMPLATE_DEVELOP}
Außerdem braucht man das nur einmal pro Unit zu deklarieren. Das macht das ganze noch etwas übersichtlicher. Das das so ist, ist dennoch unlogisch für mich. Wenn mal jemand eine typsichere gute alte Liste vom Typ TList benötigt, hier mal der Vollständige Code (Keine Objectliste). basierend auf der Idee: ![]() Hier die Deklaration.
Delphi-Quellcode:
unit u_LabelList;
{$DEFINE TEMPLATE_DEVELOP} interface uses Sysutils, Classes, Contnrs, StdCtrls; type _TLIST_ITEM = TLabel; {$I tmpl_TList.pas} TLabelList = class(_TLIST) end; implementation {$I tmpl_TList.pas} end. Hier das TLIST Template
Delphi-Quellcode:
Wenn man nicht vor hat, die Unit weiterzuentwickeln, dann kann man
//{$DEFINE TEMPLATE_DEVELOP}
{$IFNDEF TEMPLATE_DEVELOP} unit tmpl_TList; interface // copy these units into the uses clause of every unit using this template uses Sysutils, Classes, Contnrs; type _TLIST_ITEM = Pointer; {$ENDIF TEMPLATE_DEVELOP} {$IFNDEF _TLIST_SECOND_PASS} type _TLIST = class(TLIST) protected function Get(Const Index: Integer): _TLIST_ITEM; procedure Put(Const Index: Integer; Item: _TLIST_ITEM); public function Add(Const Item: _TLIST_ITEM): Integer; function Extract(Const Item: _TLIST_ITEM): _TLIST_ITEM; function First: _TLIST_ITEM; function IndexOf(Const Item: _TLIST_ITEM): Integer; procedure Insert(Const Index: Integer; Item: _TLIST_ITEM); function Last: _TLIST_ITEM; function Remove(Const Item: _TLIST_ITEM): Integer; property Items[Const Index: Integer]: _TLIST_ITEM read Get write Put; default; end; {$ENDIF _TLIST_SECOND_PASS} {$IFNDEF TEMPLATE_DEVELOP} implementation {$DEFINE _TLIST_SECOND_PASS} {$ENDIF TEMPLATE_DEVELOP} {$IFDEF _TLIST_SECOND_PASS} { _TLIST } //============================================================================== function _TLIST.Add(Const Item: _TLIST_ITEM): Integer; begin Result := inherited Add(Pointer(Item)); end; //============================================================================== function _TLIST.Extract(Const Item: _TLIST_ITEM): _TLIST_ITEM; begin Result := _TList_ITEM(inherited Extract(Pointer(Item))); end; //============================================================================== function _TLIST.First: _TLIST_ITEM; begin result := _TLIST_ITEM(inherited First); end; //============================================================================== function _TLIST.Get(Const Index: Integer): _TLIST_ITEM; begin result := _TLIST_ITEM(inherited get(Index)); end; //============================================================================== function _TLIST.IndexOf(Const Item: _TLIST_ITEM): Integer; begin result := inherited indexof(Pointer(item)); end; //============================================================================== procedure _TLIST.Insert(Const Index: Integer; Item: _TLIST_ITEM); begin inherited insert(index, Pointer(item)); end; //============================================================================== function _TLIST.Last: _TLIST_ITEM; begin result := _TList_ITEM(inherited last); end; //============================================================================== procedure _TLIST.Put(Const Index: Integer; Item: _TLIST_ITEM); begin inherited put(index, Pointer(item)); end; //============================================================================== function _TLIST.Remove(Const Item: _TLIST_ITEM): Integer; begin result := inherited remove(Pointer(item)); end; //============================================================================== //============================================================================== //============================================================================== //============================================================================== {$WARNINGS off} {$IFNDEF TEMPLATE_DEVELOP} end. {$ENDIF TEMPLATE_DEVELOP} {$ENDIF _TLIST_SECOND_PASS} {$DEFINE _TLIST_SECOND_PASS}
Delphi-Quellcode:
auch ganz oben in die Unit schreiben und spart sich das beim deklarieren von einem Nachfahr dieser Liste.
{$DEFINE TEMPLATE_DEVELOP}
Dann geht aber wie gesagt die Codevervollständigung nicht mehr. und hier der Beweis dass es eine Typsichere Liste ist ;-) |
Re: TList ableiten - Pointer -> eigener Pointertyp
neuer Beitrag *hochschieb*
|
Re: TList ableiten - Pointer -> eigener Pointertyp
weitere (echte) Templates gefunden:
(können auch gleich über LiveTemplates der IDE bequem eingefügt werden, nicht schlecht :-) ![]() ist vielleicht sogar performanter, wenn man den Quelltext der VCL nochmal neu abbildet, als über inherited zweimal aufzurufen. Gruß stoxx |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:21 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-2025 by Thomas Breitkreuz