请高手指正Bug(200分)

  • 主题发起人 DelphiDeveloper
  • 开始时间
D

DelphiDeveloper

Unregistered / Unconfirmed
GUEST, unregistred user!
unit QueryClient;

interface

uses SysUtils,Classes,Dialogs;

type

TQueryDescription = class
TableName: string;
FieldName: string;
DisplayName: string;
...
end;

TQueryDescriptionList = Class(TObject)
private
FList: TList

protected
function GetItem(Index: Integer): TQueryDescription;
procedure SetItem(Index: Integer
Item: TQueryDescription);

function GetCount:integer;
public
constructor Create;
destructor Destroy;override;

procedure Clear;
function Add(Item: TQueryDescription):integer;
function Find(const S: string
var Index: Integer): Boolean;

property Count:integer read GetCount;
property Items[Index: Integer]: TQueryDescription read GetItem Write SetItem
default;
end;
function DecomposeData(S: WideString):TQueryDescriptionList;

implementation

constructor TQueryDescriptionList.Create;
begin
inherited Create;
FList := TList.Create;
end;

destructor TQueryDescriptionList.Destroy;
begin
if FList <> nil then Clear;
FList.Free;
inherited Destroy;
end;

function TQueryDescriptionList.GetCount:integer;
begin
Result := FList.Count;
end;

procedure TQueryDescriptionList.SetItem(Index: Integer
Item: TQueryDescription);
begin
FList[Index] := Item;
end;

function TQueryDescriptionList.Add(Item: TQueryDescription):integer;
begin
Result := FList.Add(Item);
end;

function TQueryDescriptionList.GetItem(Index: Integer): TQueryDescription;
begin
if (Index < 0) or (Index >= Count) then
raise Exception.CreateFmt('索引溢出%d',[Index]);
Result := FList[Index];
end;

procedure TQueryDescriptionList.Clear;
var
QD: TQueryDescription;
begin
while FList.Count > 0 do
begin
QD := FList.Last;
QD.Free;
FList.Delete(FList.Count-1);
end;
end;

function TQueryDescriptionList.Find(const S: string
var Index: Integer): Boolean;
var
i: Integer;
begin
Result := False;
for i := 0 to Count - 1 do
if UpperCase(S) = UpperCase(Items.FieldName) then
begin
Break;
Result := True;
end;
Index := i;
end;

function DecomposeData(S: WideString):TQueryDescriptionList;
var
i,Position: integer;
stmp: string;
qdTmp: TQueryDescription;
qdlTmp: TQueryDescriptionList;
begin
Result := Nil;
qdTmp := TQueryDescription.Create;
qdlTmp := TQueryDescriptionList.Create;
Position := Pos('||',S);
try
while (Position > 0) do
begin
stmp := Copy(S,1,Position - 1);
i := Pos('&amp;&amp;',stmp);
qdTmp.TableName := Copy(stmp,1,i - 1);
stmp := Copy(stmp,i + 2,Length(stmp) - 1);
i := Pos('&amp;&amp;',stmp);
qdTmp.FieldName := Copy(stmp,1,i - 1);
stmp := Copy(stmp,i + 2,Length(stmp) - 1);
i := Pos('&amp;&amp;',stmp);
...

qdlTmp.Add(qdTmp);

S := Copy(S,Position + 2,Length(S) - Position - 1);
Position := Pos('||',S);
end;
Result := qdlTmp;

//在这里总显示为最后一行的数据???
with qdltmp do
for i := 0 to Count - 1 do
begin
Showmessage(Items.TableName + '&amp;&amp;' + Items.FieldName + Items.DisplayName);
end;

finally
qdTmp.Free;
// qdlTmp.Free;
end;
end;
end.

 
procedure TQueryDescriptionList.SetItem(Index: Integer
Item: TQueryDescription);
begin
FList[Index] := Item;
end
你没注意到TList.Items[Index]只能存放4字节吗?(一个指针)。
而你的TQueryDescription明显大于4字节(至少12字节)
所以FList[Index]:= Item明显错误。

同理
function TQueryDescriptionList.Add(Item: TQueryDescription):integer;
function TQueryDescriptionList.GetItem(Index: Integer): TQueryDescription;
实现也是错误的。

最好定义一个PQueryDescription=^TQueryDescription;然后在FList.Items[Index]中存放
PQueryDescription类型的数值。
 
to Pearl:
//而你的TQueryDescription明显大于4字节
不是吧,TQueryDescription 是一个 class,他的实例也都应该是指针吧。

to DelphiDeveloper:
问题就出在你的 qdTmp: TQueryDescription
是一个指针,你每次都把一个指向相同
地址的指针加入 List,当然最后只的结果都相同:)
你应该每次都给 qdTmp 分配一次空间(随手写的,未测试,你自己试一下):

function DecomposeData(S: WideString):TQueryDescriptionList;
var
i,Position: integer;
stmp: string;
qdTmp: TQueryDescription;
qdlTmp: TQueryDescriptionList;
begin
Result := Nil;
//qdTmp := TQueryDescription.Create
这里不要创建
qdlTmp := TQueryDescriptionList.Create;
Position := Pos('||',S);
try
while (Position > 0) do
begin
qdTmp := TQueryDescription.Create
// 在这里,循环创建
// 这样每次循环,qdTmp 都指向不同的实例,才能加进不同的结果

stmp := Copy(S,1,Position - 1);
i := Pos('&amp;&amp;',stmp);
qdTmp.TableName := Copy(stmp,1,i - 1);
stmp := Copy(stmp,i + 2,Length(stmp) - 1);
i := Pos('&amp;&amp;',stmp);
qdTmp.FieldName := Copy(stmp,1,i - 1);
stmp := Copy(stmp,i + 2,Length(stmp) - 1);
i := Pos('&amp;&amp;',stmp);
...

qdlTmp.Add(qdTmp);

S := Copy(S,Position + 2,Length(S) - Position - 1);
Position := Pos('||',S);
end;
Result := qdlTmp;

// 应该不会是相同的结果了,你再看看
with qdltmp do
for i := 0 to Count - 1 do
begin
Showmessage(Items.TableName + '&amp;&amp;' + Items.FieldName + Items.DisplayName);
end;

for i := 0 to qdltmp.Count - 1 do
// 现在你需要循环释放每一个 qdTmp,就在这个循环(这就不用我写了吧)

finally
qdTmp.Free;
// qdlTmp.Free;
end;
end;

 
按照Pearl的方法可以解决问题
 
顶部