学习 TList 类的实现[5]

先来实现 TMyList.SetCapacity.

马上会想到下面代码:

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 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.


 
   

你可能感兴趣的:(list)