2013-03-04 6 views
9

Spero di creare una sorta di "TOwnedStringList" (nome di classe è una finzione) che ho potuto costruire come:Come creare un discendente TStringList con il proprietario che libererà automaticamente TStringList?

sl := TOwnedStringList.Create(Self); 
sl.Sorted := True; 
sl.Duplicates := dupIgnore; 
sl.Add(...); 
// etc... 

Dove Self potrebbe essere una forma (per esempio), in modo che il proprietario auto libera l'elenco delle stringhe. Voglio essere in grado di evitare di chiamare me stesso sl.Free.

è possibile?

risposta

13

che sta per essere un po 'disordinato. Dovresti fare qualcosa di simile.

type 
    TOwnerComponent = class(TComponent) 
    private 
    FOwnedObject: TObject; 
    public 
    constructor Create(Owner: TComponent; OwnedObject: TObject); 
    destructor Destroy; override; 
    end; 

    TOwnedStringList = class(TStringList) 
    private 
    FOwner: TOwnerComponent; 
    public 
    constructor Create(Owner: TComponent); 
    destructor Destroy; override; 
    end; 

{ TOwnerComponent } 

constructor TOwnerComponent.Create(Owner: TComponent; OwnedObject: TObject); 
begin 
    inherited Create(Owner); 
    FOwnedObject := OwnedObject; 
end; 

destructor TOwnerComponent.Destroy; 
begin 
    FOwnedObject.Free; 
    inherited; 
end; 

{ TOwnedStringList } 

constructor TOwnedStringList.Create(Owner: TComponent); 
begin 
    inherited Create; 
    if Assigned(Owner) then 
    FOwner := TOwnerComponent.Create(Owner, Self); 
end; 

destructor TOwnedStringList.Destroy; 
begin 
    if Assigned(FOwner) and not (csDestroying in FOwner.ComponentState) then 
    begin 
    FOwner.FOwnedObject := nil; 
    FOwner.Free; 
    end; 
    inherited; 
end; 

In sostanza si crea un'istanza di TOwnerComponent che è di proprietà della Owner che si passa a TOwnedStringList.Create. Quando ciò Owner muore, distrugge la TOwnerComponent che a sua volta distrugge il vostro elenco di stringhe.

Il codice è resiliente ad una esplicita Free essere chiamato nella lista di stringhe.

+0

uno stesso trucco come con interfacce nei record – jpfollenius

+1

sembra essere molto promettente. Il costruttore TOwnerComponent dovrebbe essere creato con la direttiva 'reintroduce'? Inoltre, come posso proteggere 'TOwnedStringList' contro' sl.Create (nil) 'ed esplicito' sl.Free'? – ZigiZ

+1

'Create (nil)' sta bene. Questo significa solo, nessun proprietario, fammi prendere in carico la proprietà. O se non lo vuoi, allora genera un'eccezione. Explicit 'Free' ci vorrà un po 'di più a pensare. Sopportami. –