学习 TList 类的实现[5]
马上会想到下面代码:
procedure TMyList.SetCapacity(const Value: Integer);
begin
if FCapacity <> Value then
FCapacity := Value;
end;
但这样是远远不够的, 关键是需要分配内存, 像这样: ReallocMem(数组的起点指针, 元素个数*元素大小);
数组的起点指针即是 FList; 元素个数就是 SetCapacity 的参数: Value; 元素即是指针, Win32 指针的大小是 4 个字节, 因此可以写为: ReallocMem(FList, Value*4);
在 Win64 下的指针还会是 4 个字节吗? 还是这样写稳妥些: ReallocMem(FList, Value*SizeOf(Pointer));
把方法改写为:
procedure TMyList.SetCapacity(const Value: Integer);
begin
if FCapacity <> Value then
begin
ReallocMem(FList, Value * SizeOf(Pointer));
FCapacity := Value;
end;
end;
这还不够, 如果用户设置的 Value 值大于了列表的最大许可值(MaxListSize)怎么办? 小于了当前的元素数也不行啊, 再改写:
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;
莫名其妙地 Exit, 会让人摸不着头脑, 抛出个异常吧(使用异常类需要 uses SysUtils 单元), 譬如:
if (Value < FCount) or (Value > MaxListSize) then
raise Exception.Create('非法的数据');
再具体点, 让异常说出非法数据到底是什么:
if (Value < FCount) or (Value > MaxListSize) then
raise Exception.CreateFmt('非法数据:%d', [Value]);
TList 把抛出异常也做成了一个 Error 方法, 我们暂时就这样吧, 再次改写方法为:
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;
TMyList.SetCapacity 方法完成了, 现在完整的代码是:
unit MyList; interface uses SysUtils; {异常类 Exception 声明在 SysUtils 单元} const
MaxListSize = Maxint div ; type
PPointerList = ^TPointerList;
TPointerList = array[..MaxListSize - ] 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.
学习 TList 类的实现[5]的更多相关文章
- 学习 TList 类的实现[4]
现在准备一步步地模拟 TList 类, 建立一个自己的 TMyList. 首先, 这个类中应该包括前面提到的那个 Pointer 数组(TPointerList)的指针(PPointerList): ...
- 学习 TList 类的实现[8]
现在准备建立 Items 数组属性; 在 public 区输入下面代码:property Items[Index: Integer]: Pointer; 执行 Shift+Ctrl+C 后的代码是: ...
- 学习 TList 类的实现[1]
最近整理了一些函数列表, 算是一个宏观的安排; 等以后再碰到一些函数时就可以放置的更有次序一些. 我对函数与类的理解是: 函数是一个功能模块, 类是一个更强大的功能模块; Delphi 已经提供了很多 ...
- 学习 TList 类的实现[2]
我原来以为 TList 可能是一个链表, 其实只是一个数组而已. 你知道它包含着多大一个数组吗? MaxListSize 个!MaxListSize 是 Delphi 在 Classes 单元定义的一 ...
- 学习 TList 类的实现[6]
实现 TMyList.Add 函数. TList 中的 Add 函数用到了一个 Grow 方法, 它的原理是元素越多就为以后准备更多内存, 我们这里省略为预留 4 个元素的内存; TList 中的 A ...
- 学习 TList 类的实现[3] - 不能回避的话题: 内存分配
在 Delphi 中, 几乎所有的类型都有对应的指针类型, 譬如: Char PChar Word PWORD Double PDouble TPoint PPoint 甚至一种类型对应这着几种指针类 ...
- 学习 TList 类的实现[7]
总结目前 TMyList 已具备的功能(3 个方法.3 个属性): Add: 添加; Delete: 删除; Clear: 清空;Count: 元素总数;Capacity: 已存在的所有元素位置数;L ...
- Java虚拟机JVM学习07 类的卸载机制
Java虚拟机JVM学习07 类的卸载机制 类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就 ...
- Java虚拟机JVM学习04 类的初始化
Java虚拟机JVM学习04 类的初始化 类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始 ...
随机推荐
- PCIE知识点
引自:http://bbs.eetop.cn/thread-442072-1-1.html 1.从速度上来讲PCIE1.0标准 2.5G(8B/10B),pcie2.0标准 5.0G(8B/10B)p ...
- MSSQLid清零
truncate table [cellphone2016].[dbo].[tp_phone_9]
- HTML5 CSS3 专题 :诱人的实例 3D旋转木马效果相冊
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/32964301 首先说明一下创意的出处:http://www.zhangxinxu ...
- Golang学习途径总结
最近要进入一个新团队,新团队对异步开发好像很重视,我对异步开发技术再次做了一调研,其中Golang,之前看过一次The way to go,感觉就是简化C加协程和通道,这次又重新翻起,首先看了一下&l ...
- CPAN镜像使用帮助
https://lug.ustc.edu.cn/wiki/mirrors/help/cpan ************************************************** 使用 ...
- druid使用
https://blog.csdn.net/weinichendian/article/details/78503469
- Curator入门教程1
简介 Curator是Netflix开源的一套ZooKeeper客户端框架. Netflix在使用ZooKeeper的过程中发现ZooKeeper自带的客户端太底层, 应用方在使用的时候需要自己处理 ...
- 接Window服务(二)
接Window服务(一) ServiceController方法调用 1 public partial class Service1 : ServiceBase 2 { 3 public Servic ...
- Docker——MacOS上安装运行docker
近几年来,Docker越来越流行,使用场景也越来越广泛.为了能尽快跟上时代步伐.学习并应用到实际工作中,我也开始了Docker之旅. Docker版本 Docker共有两种版本: 社区版(Commun ...
- 嘿, 你知道吗, 再也不需要for循环了!
做一个优雅的程序员 JavaScript是一门优雅的语言, 这个'优雅'体验在JS逻辑层次处于高段位的水平, 什么意思呢, 就是一个js应用的主线剧情一定全部是函数式表达的高层可读逻辑, 还是不懂? ...