通過實驗,答案是肯定的!這使我感到很興奮,因為Delphi從誕生之日起,就限定了只能繼承於TObject的堆對象,必須通過Create和Free來建立和銷毀一個對象,而不能使用棧對象。而棧對象的好處就在於它能和其它類型一樣很方便的定義,它能自動調用構造函數和析構函數,在作用域范圍內(如函數內的局部對象)不必當心對象的建立和銷毀問題。要是Delphi具有了該功能,無意是Delphi編程者們的福音。
不過,進一步的測試卻比較失望,請看下面的代碼:
type
TMyRecord=record
private
x:Integer;
y:Integer;
public
//error:Parameterlessconstructorsnotallowedrecordtypes
// constructorCreate;
//error:Arecordcannotintroduceadestructor
// destructorTMyRecird;
constructorCreate(a:Integer);
constructorTMyRecord;overload;
constructorTMyRecord(a,b:Integer);overload;
// constructorTMyRecord(a,b:Integer);
procedureDisplay;
propertyxi:Integerreadx;
end;
{TMyRecord}
constructorTMyRecord.Create(a:Integer);
begin
x:=a;
y:=0;
end;
procedureTMyRecord.Display;
begin
ShowMessage(Format('x=%d,y=%d',[x,y]));
end;
constructorTMyRecord.TMyRecord;
begin
x:=0;
y:=0;
end;
constructorTMyRecord.TMyRecord(a,b:Integer);
begin
x:=a;
y:=b;
end;
procedureTForm1.Button1Click(Sender:TObject);
var
rec:TMyRecord;
begin
rec.TMyRecord(100,200);
rec.Display;
end;
可以看出,確實可以和C++一樣定義一個局部record對象(不需要動態建立),而且可以使用該對象的方法和屬性,請看TForm1.Button1Click方法的匯編碼(CPU調試窗口粘貼下來的):
Unit1.pas.72:begin
0045ACDC83C4F8 addesp,-$08
Unit1.pas.73:rec.TMyRecord(100,200);
0045ACDF8BC4 moveax,esp
0045ACE1B9C8000000 movecx,$000000c8
0045ACE6BA64000000 movedx,$00000064
0045ACEBE8E4FFFFFF callTMyRecord.TMyRecord
Unit1.pas.74:rec.Display;
0045ACF08BC4 moveax,esp
0045ACF2E855FFFFFF callTMyRecord.Display
Unit1.pas.75:end;
0045ACF759 popecx
0045ACF85A popedx
0045ACF9C3 ret
從匯編碼中看,定義的TMyRecord變量rec確實是標准C++棧對象一樣的,在調用其方法的時候也隱含傳遞了Self指針(mov eax,esp),也就是說,rec在這裡已經區別於普通的record變量,而是一個實實在在的“對象”變量!
但是遺憾的是,它不能定義destructor方法,雖然可以定義constructor方法(不能定義為Tobject缺省的Create方法,帶參數可以),但卻不能在定義的時候自動調用構造方法(我原本以為和C++一樣,定義一個和TMyRecord同名的constructor方法,可以自動調用的),如此一來,靜態棧對象的主要優點就喪失了,如果手工調用構造方法,和定義一個普通record變量,然後調用靜態過程沒什麼兩樣了。其實,Delphi已經把record改道這一步了,稍稍進一步就可以完完全全的使用棧對象,從技術上講一點難度都沒有,編譯器只需要在棧中分配對象變量內存和銷毀對象變量內存的同時,隱含調用一下構造方法和析構方法就可以了的。
雖然很遺憾,但是還是為Delphi的這點進步而高興,至少我們可以利用這一功能封裝record,而且使用這有限的棧對象可以不用當心對象本身的銷毀問題(record對象中動態分配的內存還是得手工釋放或者調用它的某個方法釋放)。
後記:以前在DOS下,以C/C++為主,Pascal只用過Turbo Pascal4.0,對以後Pascal的版本並不十分了解,今天看了網友housisong的留言,才知道我所謂的新功能--有限棧對象,Delphi中早就有了,如Delphi7.0就可以使用Object關鍵字定義棧對象,而且比2007的record類型還完善一些,record不能繼承,而object對象能夠繼承,看來我真是孤陋寡聞了!!!