一、TList类

1.1 1.1 TList类的属性

    由TList类的原码可以看到,TList类有如下几个特性: 

    property Capacity: Integer read FCapacity write SetCapacity;
    property Count: Integer read FCount write SetCount;
    property Items[Index: Integer]: Pointer read Get write Put; default;
    property List: PPointerList read FList;

    它们之间的关系如图:

                       

    1. 其中,值得注意的是当使用SetCount和SetCapacity函数时的各种情况;在SetCount中有这样一段代码:

        if NewCount > FCount then
          FillChar(FList^[FCount], (NewCount - FCount) * SizeOf(Pointer), 0)
        else
          for I := FCount - 1 downto NewCount do
            Delete(I);

        既是说,当NewCount > FCount时,将会把多余的空间置为空;否则,将删除(FCount - NewCount)的那些多余的Items.

    2. 在SetCapacity函数中调用了这样一个函数:

        ReallocMem(FList, NewCapacity * SizeOf(Pointer));

       此函数有两个参数(var P: Pointer; Size: Integer),它将根据这两个参数的不同值做不同的处理:

        (1)当p = nil,Size = nil时,不做任何处理;

        (2)当p = nil,Size <> nil时, 将分配空间,把p指向该空间

        (3)当p <> nil,Size = nil时, 将释放掉p所指向的空间。

        (4)当p <> nil,Size <> nil时, ReallocMem函数将不会影响到原来已有的空间。

1.2 2.2 TList类的空间分配

    TList类为了获得合适的容量,在请求增加容量时调用了Grow函数,此函数是根据你目前Capacity的大小来分配空间的;它的增长趋势是

Capacity = 0->4->8->12->12 + 16->28 + 16->...->76 + (Capacity div 4)->...

    所以,当您分配一个合适的值给Capacity时,在调用Add方法时,就可以避免多次分配内存,有利于提高程序的性能。

1.3 2.3 TList类中Assign方法中的奇怪???

    TList类中为了实现对象间的赋值,TList类实现了一个带缺省参数的方法procedure Assign(ListA: TList; AOperator: TListAssignOp = laCopy; ListB: TList = nil),而再看此方法的实现部分:

    procedure TList.Assign(ListA: TList; AOperator: TListAssignOp; ListB: TList);
    var
    I: Integer;
    LTemp, LSource: TList;
    begin
    if ListB <> nil then
    begin
        LSource := ListB;
        Assign(ListA);     // 看这段代码它递归调用了自己,你是否觉得奇怪呢?其实不然,它这里很巧妙的运用了递归。使得该方法
    end                    // 实现了TListAssignOp = (laCopy, laAnd, laOr, laXor, laSrcUnique, laDestUnique)这么几种不
    else                   // 同情况下对TList对象的赋值
        LSource := ListA;  

    case AOperator of
    laCopy:
        begin
        Clear;
        Capacity := LSource.Capacity;
        for I := 0 to LSource.Count - 1 do
        Add(LSource[I]);
       end;
    ......


posted on 2006-11-16 19:24  望天  阅读(734)  评论(0编辑  收藏  举报