先来实现 TMyList.SetCapacity.
马上会想到下面代码:
数组的起点指针即是 FList; 元素个数就是 SetCapacity 的参数: Value; 元素即是指针, Win32 指针的大小是 4 个字节, 因此可以写为: ReallocMem(FList, Value*4);
在 Win64 下的指针还会是 4 个字节吗? 还是这样写稳妥些: ReallocMem(FList, Value*SizeOf(Pointer));
把方法改写为:
马上会想到下面代码:
但这样是远远不够的, 关键是需要分配内存, 像这样: ReallocMem(数组的起点指针, 元素个数*元素大小);procedure TMyList.SetCapacity(const Value: Integer); begin if FCapacity <> Value then FCapacity := Value; end;
数组的起点指针即是 FList; 元素个数就是 SetCapacity 的参数: Value; 元素即是指针, Win32 指针的大小是 4 个字节, 因此可以写为: ReallocMem(FList, Value*4);
在 Win64 下的指针还会是 4 个字节吗? 还是这样写稳妥些: ReallocMem(FList, Value*SizeOf(Pointer));
把方法改写为:
这还不够, 如果用户设置的 Value 值大于了列表的最大许可值(MaxListSize)怎么办? 小于了当前的元素数也不行啊, 再改写:procedure TMyList.SetCapacity(const Value: Integer); begin if FCapacity <> Value then begin ReallocMem(FList, Value * SizeOf(Pointer)); FCapacity := Value; end; end;
莫名其妙地 Exit, 会让人摸不着头脑, 抛出个异常吧(使用异常类需要 uses SysUtils 单元), 譬如:procedure TMyList.SetCapacity(const Value: Integer); begin if (Value < FCount) or (Value > MaxListSize) then Exit; if FCapacity <> Value then begin ReallocMem(FList, Value * SizeOf(Pointer)); FCapacity := Value; end; end;
再具体点, 让异常说出非法数据到底是什么:if (Value < FCount) or (Value > MaxListSize) then raise Exception.Create('非法的数据');
TList 把抛出异常也做成了一个 Error 方法, 我们暂时就这样吧, 再次改写方法为:if (Value < FCount) or (Value > MaxListSize) then raise Exception.CreateFmt('非法数据:%d', [Value]);
TMyList.SetCapacity 方法完成了, 现在完整的代码是:procedure TMyList.SetCapacity(const Value: Integer); begin if (Value < FCount) or (Value > MaxListSize) then raise Exception.CreateFmt('非法数据:%d', [Value]); if FCapacity <> Value then begin ReallocMem(FList, Value * SizeOf(Pointer)); FCapacity := Value; end; end;
unit MyList; interface uses SysUtils; {异常类 Exception 声明在 SysUtils 单元} 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 if (Value < FCount) or (Value > MaxListSize) then raise Exception.CreateFmt('非法数据:%d', [Value]); if FCapacity <> Value then begin ReallocMem(FList, Value * SizeOf(Pointer)); FCapacity := Value; end; 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吧