レコード&TListのツッコミについて

8995 ワード

需要はrecordをTListに保存し,TListのItemsの各値を随時変更できることである.
 
コードは簡単です.
   MyRec = record



        MyStr: string;



        constructor Create(AMyStr: string);



end;



 



TForm4 = class(TForm)



  Button1: TButton;



  procedure Button1Click(Sender: TObject);



        public



  MyList: TList<MyRec>;



end;



 



constructor MyRec.Create(AMyStr: string);



begin



    MyStr := AMyStr;



end;



 



 



procedure TForm4.Button1Click(Sender: TObject);



begin



    MyList := TList<MyRec>.Create;



    MyList.Add(MyRec.Create('str'));



    MyList.Items[0].MyStr := 'www'; //[Error] Unit4.pas(46): E2064 Left side cannot be assigned to



    ShowMessage(MyList.Items[0].MyStr);



end;

 
 
値を付与できませんか?考えてみると、左側に取り出したのは変数値そのものであって、変数ではないので、値を付けることができません.では、私が値を取ってから値をつけてもいいですか?次のように変更されました.
 
procedure TForm4.Button1Click(Sender: TObject);



var



    ps: ^string;



begin



    MyList := TList<MyRec>.Create;



    MyList.Add(MyRec.Create('str'));



    ps := @MyList.Items[0].MyStr; //[DCC Error] Unit4.pas(45): E2036 Variable required



    ps^ := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 
 
変数でなければなりませんか?また考えてみると、左から取り出したのは変数値そのものであって、変数ではないので、アドレスを取ることができません.それは仕方なく、TListを変更するしかないので、次のように変更しました.
Tpye



PMyRec = ^MyRec;



 



procedure TForm4.Button1Click(Sender: TObject);



begin



    MyList := TList<PMyRec>.Create;



    MyList.Add(MyRec.Create('str')); //[DCC Error] Unit4.pas(42): E2010 Incompatible types: 'PMyRec' and 'MyRec'



    MyList.Items[0].MyStr := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 
 
Createがポインタを返してくれるといいですね.あまり言わないで、変更を続けます.
procedure TForm4.Button1Click(Sender: TObject);



begin



    MyList := TList<PMyRec>.Create;



    MyList.Add(@MyRec.Create('str')); //[DCC Error] Unit4.pas(42): E2036 Variable required



    MyList.Items[0].MyStr := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 
 
…….変更を続行:
procedure TForm4.Button1Click(Sender: TObject);



var



    r: MyRec;



begin



    MyList := TList<PMyRec>.Create;



    r := MyRec.Create('str');



    MyList.Add(@r);



    MyList.Items[0].MyStr := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 
 
いいように見えますが、
procedure TForm4.Button2Click(Sender: TObject);



begin



    ShowMessage(MyList.Items[0].MyStr); // Access Violation!



end;

 
 
考えてみると、rのメモリが解放されたのかもしれません.次のように変更されました.
procedure TForm4.Button1Click(Sender: TObject);



var



    p: PMyRec;



begin



    MyList := TList<PMyRec>.Create;



    New(p);



    p.Create('str');



    MyList.Add(p);



    MyList.Items[0].MyStr := 'www';



    ShowMessage(MyList.Items[0].MyStr);



end;

 
 
OKですが、面倒くさいですね.使わないときはdisposeも必要です.C++柔軟性がないような気がします.