TListの入れ子構造について

解決


ラスク  2006-03-18 01:47:11  No: 20547

TListの中にTListの要素をもつ変数を考えています。
変数はこんな感じです。
type
  cinumList = ^CList;
  CList = record
    num:integer;
    R,G,B:Byte;
    xnewnum:TList;
  end;
このリスト(List1)に値を入れておいて、
その後このリストの内容を取り出そうとすると
TList型であるxnewnumがうまく取り出せません。
なにかいい方法がないでしょうか?
今は以下の様にして取り出しています。
よろしくお願いします。

var coonum: cinumList;
    xconum,: TList;
begin
 if (List1<>nil) then
 begin
 New(coonum);
 xconum:= TList.Create;
 coonum.xnewnum:=TList.Create;
 try
 coonum:=List1.First; <==この次点で、coonum.xnewnumに値が入っていないようです。
 xconum:=coonum^.xnewnum;
 finally
 xconum.Free;
 coonum.Free;
 Dispose(coonum);
 end;


igy  2006-03-18 02:36:07  No: 20548

>coonum:=List1.First; <==この次点で、coonum.xnewnumに値が入っていないようです。

List1には、正しく値が格納されてます?


えーと  2006-03-18 06:17:23  No: 20549

インスタンスとインスタンス変数を正しく理解してないですね。

たとえば

New(coonum);

こうやって、新しくレコード型をつくったのに

coonum:=List1.First;

代入しちゃって、最初に作ったのが行方不明になっています。また、

xconum:= TList.Create;
coonum.xnewnum:=TList.Create;

これらも、すべて行方不明です。

インスタンスの実体とそれを参照する値をもつ変数をごっちゃにしてるのが原因です。


ラスク  2006-03-18 23:10:13  No: 20550

igyさん、えーとさんありがとうございました。

>igyさん
  List1を監視したところ、正しい値が入っていました。

>えーとさん
  インスタンスとインスタンス変数について全く理解していませんでした。
  今から勉強します。
  もしよかったら、TList型の入れ子構造を作成するいい方法があったら
  教えて下さい。よろしくお願いします。


えーと  2006-03-19 01:09:44  No: 20551

> もしよかったら、TList型の入れ子構造を作成するいい方法があったら

こんな感じです。

    { Private 宣言 }
  public
    List1: TList;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
PMyData = ^TMyData;
TMyData = record
  num:integer;
  R,G,B:Byte;
  xnewnum:TList;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  List1 := TList.Create;
end;

// リストに項目を一つ追加する。
procedure TForm1.Button1Click(Sender: TObject);
var
  pd: PMyData;
begin
  New(pd);
  pd^.num := 1111;
  pd^.R := 255;
  pd^.G := 123;
  pd^.B := 33;
  pd^.xnewnum := TList.Create;
  pd^.xnewnum.Add(pointer(9876));
  List1.Add(pd);
end;

// リストから項目1つを参照する。
procedure TForm1.Button2Click(Sender: TObject);
var
  pd: PMyData;
begin
  pd := PMyData(List1[0]);
  Label1.Caption := IntToStr(integer(pd^.xnewnum[0]));
end;

// 全項目を削除する
procedure TForm1.FormDestroy(Sender: TObject);
var
  i: integer;
  pd: PMyData;
begin
  for i = 0 to List1.Count-1 do
  begin
    pd := PMyData(List1[i]);
    pd^.xnewnum.Free;
    Dispose(pd);
  end;
end;

もし、xnewnum フィールドをリンクリストみたいにつかうなら

pd^.xnewnum := TList.Create;

ではなく

pd^.xnewnum := TList(TMyData のインスタンス);

のように、たんに TList にキャストして代入するだけです。
その場合は、

pd^.xnewnum.Free;

のような個別に Dispose() する必要はありません。


えーと  2006-03-19 01:11:31  No: 20552

あっ、List1.Free を忘れました。

// 全項目を削除する
procedure TForm1.FormDestroy(Sender: TObject);
var
  i: integer;
  pd: PMyData;
begin
  for i = 0 to List1.Count-1 do
  begin
    pd := PMyData(List1[i]);
    pd^.xnewnum.Free;
    Dispose(pd);
  end;

  List1.Free; // これね!
end;


ラスク  2006-03-20 22:24:19  No: 20553

えーとさん、ありがとうございました。
えーとさんから教えていただいた方法で
プログラムを組んでみたところ
うまく動きました。
ありがとうございました。
インスタンスとインスタンス変数について
もっと勉強したいと思います。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加