附錄 E
Delphi 4 增訂的 Object Pascal
附錄 E
Delphi 4 增訂的 Object Pascal
本附錄在於說明 Delphi 4 新增訂的 Object Pascal 程式語言。總結來說,Delphi 4 的 Object 1 Pascal 增訂了以下幾大部分 : 新增加數種內定資料型態。 Dynamic Arrays Method and Routine Overloading Default Parameters. Implementating interfaces by delegation,可用以下的寫法:
property MyInterface: IMyInterface read FMyInterface implements IMyInterface;
新增的內定資料型態
整數方面: 新增加 Int64 這種長度六十四位元,範圍從-2^63 to 2^63 – 1。 32-bit unsigned integer 新增加 Longword 型態,範圍從 0..4294967295。 1
除最後一項屬於 Win32 進階篇的內容之外,以本附錄補充說明第二、三章。
685
附錄
Cardinal 的範圍調整成與上述 Long
word 型態相同。 浮點數方面: Real 型態基於效率考量,由過去佔用 48-bit 調整成 64-bits, 新增加 Real48 型態,精確度與過去的 Real 相同,仍是 48-bit。
Dynamic Array
Delphi 4 問世之前,Delphi 程式設計師若需要動態長度的陣列,在不得已的情況下,往往 採用以下這種 「表面上陣列的語法,但實際自己配置管理記憶體」 的方式來處理動態陣列:
#0001 #0002 #0003 #0004 #0005 #0006 #0007 #0008 #0009 #0010 #0011 #0012 #0013 procedure TForm1.Button1Click(Sender: TObject); type TIntegerArray = array[0..0] of integer; PIntegerArray = ^TIntegerArray; var pArrayOfInteger: PIntegerArray; j: integer; begin GetMem(pArrayOfInteger, 10 * SizeOf(Integer)); for j := 0 to 9 do pArrayOfInteger^[j] := j; FreeMem(pArrayOfInteger, 10 * SizeOf(Integer)); end;
如果應用
Delphi 4 新增加的 Dynamic Array,則可改用以下的方式:
var MyFlexibleArray: array of Real;
定義之後,以 SetLength 函數改變陣列實際配置的記憶體大小,例如:
SetLength(MyFlexibleArray, 20); // 0..19
方便很多,是嗎?若想知道 Dynamic Array 實際長度,請分別以 High 與 Low 函數判斷, 傳回「-1」時,表示是一個該陣列的長度為零,例如:
686
附錄 E
Delphi 4 增訂的 Object Pascal
#0001 #0002 #0003 #0004 #0005 #0006 #0007 #0008 #0009 #0010
procedure TForm1.Button2Click(Sender: TObject); var A: array of Integer; begin ShowMessage(IntToStr(High(A))); // -1 SetLength(A, 3); ShowMessage(IntToStr(High(A))); // 3 A := nil; ShowMessage(IntToStr(High(A))); // -1 end;
上述的 0008 這列,指定 nil 值將會釋放陣列所配置到的記憶體。 值得注意的是,Compiler 對於 Dynamic Array 並不會自動進行所謂的「Copy-on-Write」。 請看以下的程式例:
#0001 #0002 #0003 #0004 #0005 #0006 #0007 #0008 #0009 #0010 procedure TForm1.Button1Click(Sender: TObject); var A, B: array of Integer; begin SetLength(A, 1); A[0] := 1; B := A; B[0] := 2; ShowMessage(IntToStr(A[0])); // ==> 2 end;
0008 這列改的雖是 B[0],但 Compiler 顯然還沒有聰明到在可能修改陣列
內容時,將陣列 內容複製一份出來(Copy on (possible) Write),於是,0009 這列程式顯示的結果仍是 2。 於是,若要進行兩陣列各索引項目一對一的內容複製,只好自行寫迴圈一一複製,或者, 採用較為簡便的寫法 ── 呼叫 Copy 函數:
#0001 #0002 #0003 #0004 #0005 #0006 #0007 #0008 #0009 #0010 #0011 procedure TForm1.Button4Click(Sender: TObject); var A, B: array of Integer; begin SetLength(A, 1); A[0] := 1; B := Copy(A, 0, 1); B[0] := 2; ShowMessage(IntToStr(A[0])); // ==> 1 ShowMessage(IntToStr(B[0])); // ==> 2 end;
687
附錄
最後,請不要將 Dynamic Array 與第二章提到的 Open Array(開放陣列)搞混了。函式參 數的開放陣列,語法雖與 Dynamic Array 差不多,但開放陣列指的是:不限定傳入函式的 陣列長度,D