TStringList = class;  PStringItem = ^TStringItem;
  TStringItem = record
    FString: string;
    FObject: TObject;
  end;  PStringItemList = ^TStringItemList;
  TStringItemList = array[0..MaxListSize] of TStringItem;  TStringListSortCompare = function(List: TStringList; Index1, Index2: Integer): Integer;  TStringList = class(TStrings)
  private
    FList: PStringItemList;
    ......
    ......
    ......
  end;procedure TStringList.ExchangeItems(Index1, Index2: Integer);
var
  Temp: Integer;
  Item1, Item2: PStringItem;
begin
  Item1 := @FList^[Index1];
  Item2 := @FList^[Index2];
  Temp := Integer(Item1^.FString);
  Integer(Item1^.FString) := Integer(Item2^.FString);
  Integer(Item2^.FString) := Temp;
  Temp := Integer(Item1^.FObject);
  Integer(Item1^.FObject) := Integer(Item2^.FObject);
  Integer(Item2^.FObject) := Temp;
end;这段代码是在TStringList源码中的一段,我想请问下,上面的过程和下面的这个过程有分别吗? 为什么要用integer强制转换?
procedure TStringList.ExchangeItems(Index1, Index2: Integer);
var
  Temp: TStringItem;
begin
  Temp := FList^[Index2];
  FList^[Index1]:= FList^[Index2];
  FList^[Index2]:= Temp;
end;是不是因为 TStringItem 中包含了 FObject: TObject 而不能直接赋值?那如果是类型
  TStringItem = record
    FString: string;
    FTest: Integer;
  end;
这个呢?

解决方案 »

  1.   

    对,如果换成Integer是可以的。
      

  2.   

    仍旧没弄明白
    是不是用integer转换后,是只交换了存储空间的访问地址,而实际存储的空间内容不交换?如果是比较复杂的结构体。如:
    TRecTest = record
      A: integer;
      B: Integer;
      C: string;
     D: TDateTime;
      ....
      X: string;
    end;是否有简单的方法来实现呢
      

  3.   

    如果不用Integer(Item1^.FString) :=..编译器会把当成字符串赋值..那样明显很笨重,既可能要处理引用计数,又可能要处理整块内存分配与移动.实际就要做到交换串内容地址指针就行了..指针是四字节,也就是一个Integer型.如果你那个结构体(record)要做交换处理,反而不宜这样做..
      

  4.   


    procedure TStringList.ExchangeItems(Index1, Index2: Integer);
    var
      Temp: TStringItem;
    begin
      Temp := FList^[Index2];
      FList^[Index1]:= FList^[Index2];
      FList^[Index2]:= Temp;
    end;如果象楼主这样使用结构体内容交换...情况会比较微妙...
    当便用结构体直接赋值时..编译器实际是把相关语句对应替换
    system.pas单元中的_CopyRecord...楼主可以仔细看看它的代码.
    那代码不大易懂,不过应该可以比较看出,,它是区分结构体里各字段类型不同而不同处理的,
    不是单纯块内存复制..
      

  5.   

    搂住学过c++没,对链表了解一下,对了解Tstringlist有帮助
      

  6.   

    确实如 halfdream(哈欠)大大所说,使用
    procedure TStringList.ExchangeItems(Index1, Index2: Integer);
    var
      Temp: TStringItem;
    begin
      Temp := FList^[Index2];
      FList^[Index1]:= FList^[Index2];
      FList^[Index2]:= Temp;
    end;
    是比较微秒的。我想可能对一些较复杂的结构体 容易出现错误(如结构体内包含了另外的一些结构体或一些类),所以交换访问地址应该是保险且高效的方法。刚刚也看了下system.pas单元里的_CopyRecord过程,但小弟水平有限,愣是没看懂。我经常编写一些自定义的结构体的列表,RecordList,编写模式就是参考TStringList。上面的方法是为了实现一个结构体列表内部的排序。对于一些较复杂的结构体,如果采用单独对每个项目进行访问地址转换,貌似也是有点繁琐,不知道是否有更好的方法来实现结构体列表的排序呢? 异或者是可以用另一种类型来储存结构体列表。
      

  7.   

    同意halfdream(哈欠) 的说法