现在准备一步步地模拟 TList 类, 建立一个自己的 TMyList.
首先, 这个类中应该包括前面提到的那个 Pointer 数组(TPointerList)的指针(PPointerList):
譬如当前列表中有 10 个元素时, 其实列表已经提前申请出更多位置, 这样就不必每次添加每次申请内存, 从而提高了效率.
这个 FCapacity 字段就表示已申请的可放置元素位置的总数.
不过 List 属性应该是只读的, 它就是那个核心数组的指针, 对它的赋值应该通过更多其他的方法.
修改如下:
Add 方法的参数应该是一个指针(TList 就是存放指针的吗), 如果需要同时返回元素的位置, 应该定义成函数;
Delete 是删除指定位置上的元素, 参数是个位置号;
Clear 是清除列表, 对象释放(Destroy)时也应该执行此过程.
综上所述, 修改如下:
因为 MaxListSize、TPointerList、PPointerList 都是在 Classes 单元定义的, 为了省略 uses Classes, 在 MyList 单元中重新做了定义.
首先, 这个类中应该包括前面提到的那个 Pointer 数组(TPointerList)的指针(PPointerList):
既然是一个列表, 应该有 Count 字段:TMyList = class(TObject) FList: PPointerList; end;
TList 类还有一个 FCapacity 字段.TMyList = class(TObject) FList: PPointerList; FCount: Integer; end;
譬如当前列表中有 10 个元素时, 其实列表已经提前申请出更多位置, 这样就不必每次添加每次申请内存, 从而提高了效率.
这个 FCapacity 字段就表示已申请的可放置元素位置的总数.
它们都应该是私有的:TMyList = class(TObject) FList: PPointerList; FCount: Integer; FCapacity: Integer; end;
应该用属性操作它们:TMyList = class(TObject) private FList: PPointerList; FCount: Integer; FCapacity: Integer; public end;
自动建立后的属性:unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) end; {--------------------------------} TMyList = class(TObject) private FList: PPointerList; FCount: Integer; FCapacity: Integer; public property Capacity: Integer; {光标放在属性上, 执行 Shift+Ctrl+C, 自动建立属性} property Count: Integer; property List: PPointerList; end; {--------------------------------} var Form1: TForm1; implementation {$R *.dfm} end.
在 TList 中, SetCount 和 SetCapacity 方法都是放在 protected 区以供子类使用, 这里暂时不考虑继承的问题, 就让它们先在 private 区吧;unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) end; {--------------------------------} TMyList = class(TObject) private FList: PPointerList; FCount: Integer; FCapacity: Integer; procedure SetCapacity(const Value: Integer); procedure SetCount(const Value: Integer); procedure SetList(const Value: PPointerList); public property Capacity: Integer read FCapacity write SetCapacity; property Count: Integer read FCount write SetCount; property List: PPointerList read FList write SetList; end; {--------------------------------} var Form1: TForm1; implementation {$R *.dfm} { TMyList } procedure TMyList.SetCapacity(const Value: Integer); begin FCapacity := Value; end; procedure TMyList.SetCount(const Value: Integer); begin FCount := Value; end; procedure TMyList.SetList(const Value: PPointerList); begin FList := Value; end; end.
不过 List 属性应该是只读的, 它就是那个核心数组的指针, 对它的赋值应该通过更多其他的方法.
修改如下:
作为一个列表, 最起码应该有 Add、Delete、Clear 方法.unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) end; {--------------------------------} TMyList = class(TObject) private FList: PPointerList; FCount: Integer; FCapacity: Integer; procedure SetCapacity(const Value: Integer); procedure SetCount(const Value: Integer); public property Capacity: Integer read FCapacity write SetCapacity; property Count: Integer read FCount write SetCount; property List: PPointerList read FList; end; {--------------------------------} var Form1: TForm1; implementation {$R *.dfm} { TMyList } procedure TMyList.SetCapacity(const Value: Integer); begin FCapacity := Value; end; procedure TMyList.SetCount(const Value: Integer); begin FCount := Value; end; end.
Add 方法的参数应该是一个指针(TList 就是存放指针的吗), 如果需要同时返回元素的位置, 应该定义成函数;
Delete 是删除指定位置上的元素, 参数是个位置号;
Clear 是清除列表, 对象释放(Destroy)时也应该执行此过程.
综上所述, 修改如下:
为了让代码更清晰, 还是把这个类相关的所有代码放到一个独立的单元吧(新建一个单元, 我们把它保存为: MyList.pas).unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) end; {--------------------------------} TMyList = class(TObject) private FList: PPointerList; FCount: Integer; FCapacity: Integer; procedure SetCapacity(const Value: Integer); procedure SetCount(const Value: Integer); public destructor Destroy; override; {覆盖父类的 Destroy 方法} function Add(Item: Pointer): Integer; procedure Clear; {在 TList 中这是个虚方法, 以备子类覆盖} procedure Delete(Index: Integer); property Capacity: Integer read FCapacity write SetCapacity; property Count: Integer read FCount write SetCount; property List: PPointerList read FList; end; {--------------------------------} var Form1: TForm1; implementation {$R *.dfm} { TMyList } function TMyList.Add(Item: Pointer): Integer; begin end; procedure TMyList.Clear; begin end; procedure TMyList.Delete(Index: Integer); begin end; destructor TMyList.Destroy; begin Clear; {在类释放时同时清除列表} inherited; {在 TList 中没有这句, 大概是因为它的父类也没什么可继承的} end; procedure TMyList.SetCapacity(const Value: Integer); begin FCapacity := Value; end; procedure TMyList.SetCount(const Value: Integer); begin FCount := Value; end; end.
因为 MaxListSize、TPointerList、PPointerList 都是在 Classes 单元定义的, 为了省略 uses Classes, 在 MyList 单元中重新做了定义.
至此, 类的轮廓已经出来, 该实现一下这些方法了.unit MyList; interface const MaxListSize = Maxint div 16; type PPointerList = ^TPointerList; TPointerList = array[0..MaxListSize - 1] of Pointer; TMyList = class(TObject) private FList: PPointerList; FCount: Integer; FCapacity: Integer; procedure SetCapacity(const Value: Integer); procedure SetCount(const Value: Integer); public destructor Destroy; override; function Add(Item: Pointer): Integer; procedure Clear; procedure Delete(Index: Integer); property Capacity: Integer read FCapacity write SetCapacity; property Count: Integer read FCount write SetCount; property List: PPointerList read FList; end; implementation { TMyList } function TMyList.Add(Item: Pointer): Integer; begin end; procedure TMyList.Clear; begin end; procedure TMyList.Delete(Index: Integer); begin end; destructor TMyList.Destroy; begin Clear; inherited; end; procedure TMyList.SetCapacity(const Value: Integer); begin end; procedure TMyList.SetCount(const Value: Integer); begin end; end.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧