2013-03-04 20 views
9

tôi hy vọng sẽ tạo ra một cái gì đó giống như một "TOwnedStringList" (tên lớp là một hư cấu) mà tôi có thể xây dựng như:Làm thế nào để tạo ra một hậu duệ TStringList với Chủ sở hữu sẽ tự động giải phóng TStringList?

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

đâu Self có thể là một mẫu (ví dụ), do đó chủ đầu tư sẽ tự động miễn phí các StringList. Tôi muốn có thể tránh tự gọi số sl.Free.

Điều này có thể không?

Trả lời

13

Điều đó sẽ hơi lộn xộn một chút. Bạn sẽ cần phải làm một cái gì đó như thế này.

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; 

Về cơ bản bạn tạo một thể hiện của TOwnerComponent được sở hữu bởi các Owner mà bạn vượt qua để TOwnedStringList.Create. Khi đó Owner chết, nó phá hủy các TOwnerComponent mà lần lượt phá hủy danh sách chuỗi của bạn.

Mã này có khả năng đàn hồi để rõ ràng Free đang được gọi trong danh sách chuỗi.

+0

+1 Mẹo tương tự như với giao diện trong hồ sơ – jpfollenius

+1

Có vẻ đầy hứa hẹn. Nếu hàm tạo TOwnerComponent được tạo bằng chỉ thị 'reintroduce'? Ngoài ra, Làm thế nào tôi có thể bảo vệ 'TOwnedStringList' chống lại' sl.Create (nil) 'và' sl.Free' rõ ràng? – ZigiZ

+1

'Tạo (nil)' là tốt. Điều đó chỉ có nghĩa là, không có chủ sở hữu, hãy để tôi chịu trách nhiệm về quyền sở hữu. Hoặc nếu bạn không muốn điều đó, thì hãy đưa ra một ngoại lệ. Rõ ràng 'Free' sẽ mất một chút suy nghĩ về. Chịu với tôi. –

Các vấn đề liên quan