全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1121
推到 Plurk!
推到 Facebook!

如何複製一個類別內容

尚未結案
sam_000
一般會員


發表:27
回覆:47
積分:14
註冊:2003-09-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-05-05 13:58:47 IP:211.22.xxx.xxx 未訂閱
各位前輩好 我想用stream方法複製一個自訂類別的內容,編譯無問題,但執行時就有error,想請前輩指正, 謝謝 程式如下 type TMyObject = class fValue1 : string; fValue2 : string; end; procedure TFstack.FormCreate(Sender: TObject); begin mylist:=tlist.Create ; end; procedure TFstack.Button1Click(Sender: TObject);//產生一個TMyObject物件 var myobj:TMyObject; begin mystr:=inttostr(ii 1) ; myobj:=TMyObject.Create; myobj.fValue1 := mystr; myobj.fValue2 := mystr; mylist.Add(myobj); ii:=ii 1; button3.Click ; end; procedure Tfstack.Button2Click(Sender: TObject);//複製一個TMyObject物 var myobj,myobj1:TMyObject;memstream:tmemorystream;i:integer; begin memstream:=tmemorystream.Create ; myobj:= mylist.items[0] ; with memstream do begin write(myobj,sizeof(myobj)); position:=0 ; myobj1:=tmyobject(read(myobj1,sizeof(myobj1))); mylist.Add(myobj1); ii:=ii 1; end; memstream.free; end; procedure TFstack.Button3Click(Sender: TObject);// 顯示TMyObject物件內 var myobj:TMyObject; begin myobj:=Mylist.items[ii-1]; e1.Text :='valu1,2=' (myobj).fValue2 ',' (myobj).fValue1;//程式執行至此就會出現錯誤 e2.Text:=inttostr(mylist.Count ); end;
jest0024
高階會員


發表:11
回覆:310
積分:224
註冊:2002-11-24

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-05-05 15:37:48 IP:61.60.xxx.xxx 未訂閱
不管元件還是類別,無法直接拿元件的指標來複置整個元件, 假設 T=TMyObj; stream.write(T,Sizeof(T)); 寫入STREAM的資料是一個指標,SIZE=4 必須依照元件內的資料寫進去. TObj = class a,b:Integer; procedure LoadStream(Stream:TStream); procedure SaveStream(Stream:TStream); end; TObj.LoadStream(Stream:TStream); beign Stream.read(a,sizeof(a)); Stream.read(b,sizeof(b)); end; TObj.SaveStream(Stream:TStream); begin Stream.write(a,sizeof(a)); Stream.write(b,sizeof(b)); end; 學而時習之不亦樂乎! 發表人 - jest0024 於 2004/05/05 15:42:40
sam_000
一般會員


發表:27
回覆:47
積分:14
註冊:2003-09-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-05-05 18:56:27 IP:211.22.xxx.xxx 未訂閱
前輩好 依您的提示我把程式改成下面仍會有 'Abstract error'出現,煩請前輩幫我看一下,是否有哪裡出錯,謝謝 procedure TFstack.Button1Click(Sender: TObject); var myobj:TObj; begin myobj:=TObj.Create; myobj.a := ii; myobj.b:=ii; mylist.Add(myobj); ii:=ii 1; button3.Click ; end; procedure Tfstack.Button2Click(Sender: TObject); var myobj,myobj1:TObj;stream:tstream;i:integer; begin stream:=tstream.Create ; myobj:= mylist.items[1] ;//複製mylist中的第二個Tobj with stream do begin myobj.SaveStream(stream); myobj1.LoadStream(stream); mylist.Add(myobj1); ii:=ii 1; end; stream.free; end;'
TATSU
版主


發表:50
回覆:135
積分:62
註冊:2003-01-16

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-05-05 20:47:38 IP:219.77.xxx.xxx 未訂閱
 
type
  TMyObject = class
    fValue1 : string;
    fValue2 : string;
  end;     procedure TFstack.FormCreate(Sender: TObject);
begin
  mylist := tlist.Create ;
end;    procedure TFstack.Button1Click(Sender: TObject);//產生一個TMyObject物件
var
  myobj:TMyObject;
  myStr : String ;
begin
  mystr := inttostr(ii   1) ;
  myobj := TMyObject.Create;
  myobj.fValue1  := mystr;
  myobj.fValue2  := mystr;
  mylist.Add(myobj);
  Inc(ii)
  ShowMyObject ;  
end;    procedure Tfstack.Button2Click(Sender: TObject);//複製一個TMyObject物
var
  myobj, myobj1 : TMyObject ; 
begin
  MyObj  := MyList.Items[0] ;
  MyObj1 := TMyObject.Create;
  MyObj1.fvalue1 := MyObj.fvalue1 ;
  MyObj1.fvalue2 := MyObj.fvalue2 ;
  MyList.Add(MyObj1) ;
  Inc(ii) ;
end;    procedure TFstack.Button3Click(Sender: TObject);// 顯示TMyObject物件內
var
  myobj:TMyObject;
begin
  ShowMyObject ;  
end;    procedure TFstack.ShowMyObject ;
var
  myObj : TMyObject ;
begin
  MyOBj := MyList.Items[ (MyList.Count - 1) ] ;
  Edit1.Text := 'Value 1, 2 = '   MyObj.fValue1   
                ','   MyObj.fValue2 ;
  Edti2.Text := IntToStr(MyList.Count) ;
end;
 
離線閱讀程式
pgdennis
資深會員


發表:41
回覆:526
積分:443
註冊:2002-05-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-05-05 23:21:07 IP:210.64.xxx.xxx 未訂閱
其實你如果是要複製一個物件內容,通常是用Assign函式 TPersistent的 procedure Assign(Source: TPersistent); virtual; 大部分delphi元件都是繼承TPersistent,或多或少都有Override Assign函式 建議你維持一貫的程式風格,所以你應該把複製的功能寫在Assign函式 大致如下:
procedure TMyObject.Assign(Source: TPersistent);
begin
  if Source is TMyObject  then
  begin
    fValue1:=Source.fValue1;
    fValue2:=Source.fValue2;
  end;
  //inherited Assign(Source);
end;
所以你的ButtonClick2可以改成(這部份借用TATSU兄的CODE)
  MyObj  := MyList.Items[0] ;
  MyObj1 := TMyObject.Create;
  MyObj1.ASSIGN(MyObj);
  MyList.Add(MyObj1) ;
< >...這樣複製物件內容,也比較好管理,雖然你是繼承 >< > 永遠追不上技術更新的速度 發表人 -
------
星期一,二...無窮迴圈@@
jest0024
高階會員


發表:11
回覆:310
積分:224
註冊:2002-11-24

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-05-06 00:31:11 IP:210.66.xxx.xxx 未訂閱
當OBJ要使用時一定要建構,否則他只是指向一個指標(含空指標) Obj1:=TObj.Create; // Obj2:=TObj.Create; //必須先建構,才能複製 Obj1.SaveStream(Stream); Stream.Position:=0; //先Seek 0 Obj2.LoadStream(Stream); 學而時習之不亦樂乎!
sam_000
一般會員


發表:27
回覆:47
積分:14
註冊:2003-09-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-05-06 23:24:58 IP:211.22.xxx.xxx 未訂閱
謝謝幾位前輩的指點,我試了每位前輩的方法結果如下: 版主:功能正常, 但如果該類別欄位多有點不方便 pgdennis前輩:加入procedure TmyObject.Assign(Source: TPersistent) 會出現'incompatible types'的error,該如何處理 jest0024前輩:修改成Obj1:=TObj.Create; // Obj2:=TObj.Create; //必須先建構,才能複製 Obj1.SaveStream(Stream); Stream.Position:=0; //先Seek 0 Obj2.LoadStream(Stream); 仍有error出現 煩請各位前輩指正 謝謝
James
高階會員


發表:10
回覆:290
積分:220
註冊:2002-07-25

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-05-07 00:40:12 IP:218.170.xxx.xxx 未訂閱
因為 TStream 是抽象類別 ,所以你不能這樣寫 stream:=tstream.Create ; 或許可以改成 stream:=TMemoryStream.Create ;
sam_000
一般會員


發表:27
回覆:47
積分:14
註冊:2003-09-15

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-05-09 22:05:03 IP:61.227.xxx.xxx 未訂閱
可以了,將stream改成memorystream運作正常,謝謝James前輩 ,亦謝謝pgdennis 前輩及版主的指點,只是只能給一個人分數,Jest0024前輩得分,謝謝
系統時間:2024-05-15 17:09:12
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!