【问题标题】:How to create a TStringList descendant with Owner that will auto free the TStringList?如何创建一个带有 Owner 的 TStringList 后代,它将自动释放 TStringList?
【发布时间】:2025-11-29 23:05:02
【问题描述】:

我希望创建类似“TOwnedStringList”(类名是虚构的)之类的东西,我可以将其构造为:

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

其中Self 可以是一个表单(例如),以便所有者将自动释放字符串列表。 我希望能够避免自己打电话给sl.Free

这可能吗?

【问题讨论】:

    标签: delphi delphi-7


    【解决方案1】:

    这会有点混乱。你需要做这样的事情。

    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;
    

    基本上,您创建了一个TOwnerComponent 的实例,该实例由您传递给TOwnedStringList.CreateOwner 拥有。当Owner 死亡时,它会破坏TOwnerComponent,进而破坏你的字符串列表。

    代码对在字符串列表上调用的显式Free 具有弹性。

    【讨论】:

    • 看起来很有希望。是否应该使用 reintroduce 指令创建 TOwnerComponent 构造函数?另外,如何保护TOwnedStringList 免受sl.Create(nil) 和显式sl.Free 的影响?
    • Create(nil) 很好。那只是意味着,没有所有者,让我负责所有权。或者,如果您不希望这样,请引发异常。明确的Free 需要更多的思考。忍受我。
    • if Assigned(FOwner) and not (csDestroying in FOwner.ComponentState) 怎么样?
    最近更新 更多