Salve a tutti!
Ho creato una mia classe, e nel mio programma ho la necessita di utilizzare numerose istanze di questa classe, tenute in una lista usando TFPObjectList.
Il tutto funziona bene, ma quando devo usare la mia classe devo fare:
TMyClasse(Lista[i]).miaProprieta
Lo faccio e il tutto funziona bene!
Pero mi chiedevo, è possibile creare una classe che mi permetta di usare la mia in questo modo?
MiaClasse[i].miaProprieta
in pratica dovrei usare una lista che contiene la mia classe!
Come posso fare?
Grazie a tutti!
P.S. Sto lavorando ad un progetto per la gestione dei file GPS
ci sono molte strade per fare quello che dici
una abbastanza semplice (di sicuro non la più efficiente) è quella di fare una classe wrapper per usare TFPObjectList con tuoi metodi e proprietà
es:
TMyClasseManager = class(TObject)
private
lista: TFPObjectList;
public
constructor Create...
destructor Destroy...
function New: TMyClasse;
procedure Add(instance: TMyClasse);
property Items... default
end;
Gerazie Nomo,
Mi hai dato lo spunto per guardare come è stato fatto TFPObjectList;
Ed ho visto che anche questa è una classe wrapper di TFPlist;
Ho creato questo codice che sembra funzionare, ma è possibile renderlo più efficiente?
unit Unit3;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,contnrs;
type
{ Tcane }
TCane = class(TObject) // Classe base di prova
private
FNome:string;
public
Constructor Create;
destructor Destroy; override;
Property Nome:string read Fnome write Fnome;
end;
{ TCani }
TCani = class(TObject) // Classe Lista dei Cani
Private
Flist:TFPObjectList; // lista interna
function GetCount: integer;
function GetItem(Idx: integer): Tcane; // Restituisce istanza di Tcane
procedure SetItem(Idx: integer; AValue: Tcane); // Crea istanza di Tcane
Public
constructor Create;
Destructor Destroy; override;
Function New(Aname:string):Integer; // aggiunge un cane alla lista
Procedure Delete(Idx:Integer); // Cancella un cane dalla lista
Property Items [Idx:integer]: Tcane read GetItem write SetItem; default;
Property Count:integer read GetCount;
end;
implementation
{ TCani }
function TCani.GetItem(Idx: integer): Tcane;
begin // restituisce istanza di Tcane alla posizione Idx
Result:=Tcane(FList[Idx]);
end;
function TCani.GetCount: integer;
begin // Totale dei cani presenti
Result:=Flist.Count;
end;
procedure TCani.SetItem(Idx: integer; AValue: Tcane);
begin // Imposta proprieta del cane Idx
Flist[Idx]:=AValue;
end;
constructor TCani.Create;
begin // creo il componente
inherited Create;
FList := TFPObjectList.Create;
end;
destructor TCani.Destroy;
begin // Distruggo il componente
if (FList <> nil) then
begin
Flist.Clear;
FList.Destroy;
end;
inherited Destroy;
end;
function TCani.New(Aname: string): Integer;
var cane:Tcane;
begin // Creo una nuova istanza del cane e lo aggiungo alla lista
cane:=TCane.Create;
cane.Nome:=Aname;
Result:=Flist.Add(cane);
end;
procedure TCani.Delete(Idx: Integer);
begin // cancello il cane
flist.Delete(idx); // cancello istanza sulla lista
end;
{ Tcane }
constructor TCane.Create;
begin
inherited Create;
end;
destructor Tcane.Destroy;
begin
inherited Destroy;
end;
end.
Ovviamente ho iserito solo le cose di base per provare se tutto funziona!
Grazie
TListaSpecializzata = class(TList)
public
property Items[index : integer] : <lamiaclasse> read getItem write setItem; default;
end;
In questo modo l'accesso ai dati è "nascosto" dentro il metodo get e set. Qui esegui il cast nel get e non devi più farlo da fuori.
con la keyword "default" indichi al compilatore di fare riferimento a quella proprietà quando trova una costruzione sintattica del tipo:
istanzaDellaMiaLista[indice] := istanza;
istanza := istanzaDellaMiaClasse[indice];
Spero di essere stato chiaro e di non aver creato più confusione di prima ... ;)
Stilgar