说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Delphi 4增訂的Object Pascal

HTML文档下载 WORD文档下载 PDF文档下载
Delphi 4增訂的Object Pascal

總結來說,Delphi 4的Object 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。

Cardinal的範圍調整成與上述Longword型態相同。

浮點數方面:

Real型態基於效率考量,由過去佔用48-bit調整成64-bits,

新增加Real48型態,精確度與過去的Real相同,仍是48-bit。

Dynamic Array

Delphi 4問世之前,Delphi程式設計師若需要動態長度的陣列,在不得已的情況下,往往採用以下這種「表面上陣列的語法,但實際自己配置管理記憶體」的方式來處理動態陣列:

#0001 procedure TForm1.Button1Click(Sender: TObject);

#0002 type

#0003 TIntegerArray = array[0..0] of integer;

#0004 PIntegerArray = ^TIntegerArray;

#0005 var

#0006 pArrayOfInteger: PIntegerArray;

#0007 j: integer;

#0008 begin

#0009 GetMem(pArrayOfInteger

10 * SizeOf(Integer));

#0010 for j := 0 to 9 do

#0011 pArrayOfInteger^[j] := j;

#0012 FreeMem(pArrayOfInteger

10 * SizeOf(Integer));

#0013 end;

如果應用Delphi 4新增加的Dynamic Array,則可改用以下的方式:

var MyFlexibleArray: array of Real;

定義之後,以 SetLength 函數改變陣列實際配置的記憶體大小,例如:

SetLength(MyFlexibleArray

20); // 0..19

方便很多,是嗎?若想知道Dynamic Array實際長度,請分別以High與Low函數判斷,傳回「-1」時,表示是一個該陣列的長度為零,例如:

#0001 procedure TForm1.Button2Click(Sender: TObject);

#0002 var

#0003 A: array of Integer;

#0004 begin

#0005 ShowMessage(IntToStr(High(A))); // -1

#0006 SetLength(A

3);

#0007 ShowMessage(IntToStr(High(A))); // 3

#0008 A := nil;

#0009 ShowMessage(IntToStr(High(A))); // -1

#0010 end;

上述的0008這列,指定nil值將會釋放陣列所配置到的記憶體。

值得注意的是,Compiler對於Dynamic Array並不會自動進行所謂的「Copy-on-Write」。請看以下的程式例:

#0001 procedure TForm1.Button1Click(Sender: TObject);

#0002 var

#0003 A

B: array of Integer;

#0004 begin

#0005 SetLength(A

1);

#0006 A[0] := 1;

#0007 B := A;

#0008 B[0] := 2;

#0009 ShowMessage(IntToStr(A[0])); // ==> 2

#0010 end;

0008這列改的雖是B[0],但Compiler顯然還沒有聰明到在可能修改陣列內容時,將陣列內容複製一份出來(Copy on (possible) Write),於是,0009這列程式顯示的結果仍是2。

於是,若要進行兩陣列各索引項目一對一的內容複製,只好自行寫迴圈一一複製,或者,採用較為簡便的寫法 ── 呼叫Copy函數:

#0001 procedure TForm1.Button4Click(Sender: TObject);

#0002 var

#0003 A

B: array of Integer;

#0004 begin

#0005 SetLength(A

1);

#0006 A[0] := 1;

#0007 B := Copy(A

0

1);

#0008 B[0] := 2;

#0009 ShowMessage(IntToStr(A[0])); // ==> 1

#0010 ShowMessage(IntToStr(B[0])); // ==> 2

#0011 end;

最後,請不要將Dynamic Array與第二章提到的Open Array(開放陣列)搞混了。函式參數的開放陣列,語法雖與Dynamic Array差不多,但開放陣列指的是:不限定傳入函式的陣列長度,Dynamic Array則是指:可變長度的陣列,兩者畢竟有所不同。以下是一則我準備的程式範例,不難看出兩者之間的差異:

#0001 type

#0002 TDynamicInteger = array of integer;

#0003

#0004 procedure Clear_OpenArray(var A: array of Integer);

#0005 var

#0006 I: Integer;

#0007 begin

#0008 for I := 0 to High(A) do A[I] := 0;

#0009 // SetLength(A

20); // 不可以這麼寫

#0010 end;

#0011

#0012 // 注意

以下兩種寫法又有不同喔

#0013 // I: procedure Clear_DynamicArray(A: TDynamicInteger);

#0014 // II: procedure Clear_DynamicArray(var A: TDynamicInteger);

#0015 procedure Clear_DynamicArray(var A: TDynamicInteger);

#0016 var

#0017 I: Integer;

#0018 begin

#0019 for I := 0 to High(A) do A[I] := 0;

#0020 SetLength(A

20); // 如果是Dynamic Array

可以這麼寫

#0021 end;

#0022

#0023 procedure TForm1.Button3Click(Sender: TObject);

#0024 var

#0025 A: TDynamicInteger;

#0026 begin

#0027 SetLength(A

3);

#0028 Clear_OpenArray(A);

#0029 ShowMessage(IntToStr(High(A))); // -1

#0030 Clear_DynamicArray(A);

#0031 // 以下這列的結果

要看 Cleary_DynamicArray 的

#0032 // 參數有沒有寫 var

#0033 ShowMessage(IntToStr(High(A)));

#0034 end;

請幫我注意0004的Clear_OpenArray,傳入的是「由整數構成的陣列,不限定陣列的長度」,0015的Clear_DynamicArray的寫法則是「接受一個可變動陣列長度的動態陣列」,若不這樣寫,當場就變成了開放陣列了。

Method and Routine Overloading

所謂的Method Overloading,簡單地說:一個以上的函式使用相同的函式名稱。這項特性是Object Pascal長久以來一直有人想要卻一直沒有支援的期盼,終於,Delphi 4多了一個保留字:overload ── 相同名稱的兩個函式,只要在宣告時額外加上overload,即使函式的參數型態不同,Delphi也會視呼叫當時傳入的參數資料型態,決定該呼叫哪一個函式。例如以下這則例子:

#0001 // 兩個 Divide 都必須寫overload保留字

#0002 function Divide(X

Y: Double): Double; overload;

#0003 begin

#0004 Result := X / Y;

#0005 end;

#0006

#0007 function Divide(X

Y: Integer): Integer; overload;

#0008 begin

#0009 Result := X div Y;

#0010 end;

#0011

#0012 procedure TForm1.Button1Click(Sender: TObject);

#0013 var

#0014 a

b

c: integer;

#0015 i

j

k: Double;

#0016 begin

#0017 a := 10;

#0018 b := 3;

#0019 i := 10;

#0020 j := 3;

#0021 c := Divide(a

b);

#0022 k := Divide(i

j);

#0023 ShowMessage(IntToStr(c)); // 3

#0024 ShowMessage(FloatToStr(k)); // 3.333333...

#0025 end;

請幫我注意到0002與0007這兩列的Divide函數,函數名稱相同,但傳入的參數型態與函數的傳回值並不相同,即使如此,0023與0024呼叫到Divide時,還是會視當時參數的型態型態,決定該呼叫哪一個Divide。

很方便,是嗎?有了這項特性,我們就可以寫出應用範圍更廣彈性更大的函數──卻不必為每一種情況各自取一個函數名稱,同時,這項特性也使得函數呼叫的方式更為一致,真是一項早該支援的特性。除了一般的程序與函數,物件的方法也可以採用overload寫法,對於「物件.方法」的撰寫與呼叫,肯定更能提供簡便與彈性。

overload可不可以應用在不同的兩個單元呢?答案是可以的,但是完全相同的函式宣告不能再寫一次。例如上述程式的0007-0010,可以移到其他單元,原來的單元只要uses這個新的單元,函數呼叫時仍然有Overloading的效果。可是,如果將0007-0010的程式碼移到其他單元卻忘了刪除原來位置的程式,換句話說,兩個單元各有一個完全長得一樣的函式,編譯時Delphi就搞不清楚了,結果自然是無法編譯。當然啦!同一個單元同一個範圍發生這樣事也是不許的,各Overloading的函式,在函式宣告上多少總有些不同。

Default Parameters

過去,函式如果定義了六個參數,那麼,寫作函式呼叫的原始碼時,就一定得乖乖地傳入六個參數,不許多也不許少。若是應用「Default Parameters」,可以只傳入五個(或者更少)。那...,那其他沒給的參數怎麼辦?沒關係,函式內部的程式將自動以預設值代入,稍後我會說明其寫法。

舉例來說,Windows API中有一個蠻好用的函數叫MessageBox,呼叫此函數將出現一通用對話盒,不管是顯示訊息或者徵詢使用者意見,都十分好用。像是以下這道敘述將產生如次頁的對話盒,提醒使用者定期備份資料:

Application.MessageBox('程式要結束了喔! 請記得定期備份資料'

'訊息'

MB_OK + MB_ICONINFORMATION);

除了顯示資料,經由最後一個參數,彈性地搭配各位元旗標,就可以製作出不同按鈕的對話盒,詢問使用者「是」、「否」、「取消」等簡單的問題。

應用Default Parameters的寫法,我們可以寫一個類似以下的函數:

#0001 function MyMessageBox(Prompt: string;

#0002 Caption: string = '訊息';

#0003 Flag: LongInt = MB_OK + MB_ICONINFORMATION): integer;

#0004 begin

#0005 Result := Application.MessageBox(

#0006 PChar(Prompt)

PChar(Caption)

Flag);

#0007 end;

#0008

#0009 procedure TForm1.Button1Click(Sender: TObject);

#0010 begin

#0011 MyMessageBox('程式要結束了喔! 請記得定期備份資料');

#0012 end;

如此一來,我們既能有一個完整支援MessageBox的函數,只想顯示文字時,也能有一個精簡型式的函數可用。大家應該明顯看得出來:不必寫成兩個函數。

觀察上述程式的寫法,其實也蠻容易的,只不過是在定義函數參數時,一併給定初值。

不過,實際動手去寫時,還是會發現一些限制。繼續這個例子來說,參數的預設值一定得是常數,另外,如果某一個參數開始給預設值,接在後頭的參數也必須用Default Parameters的寫法。為什麼得有這項限制?以上例來說,如果0001-0003我改成:

#0001 function MyMessageBox(Prompt: string;

#0002 Caption: string = '訊息';

#0003 Flag: LongInt): integer;

那麼,只傳入兩個參數進去時,Delphi怎麼知道第二個參數該是Captioin或者是「Caption按預設值,第二個參數代入Flag」。Visual Basic對此的解法是在呼叫函數時,一併寫明各參數名稱與值的對應,由於這個緣故,Visual Basic甚至允許參數的次序不同也沒關係,因為,各參數與其值的對應關係在呼叫函式時已一併註明清楚。很可惜的,Delphi 4雖有Default Parametets,但還不支援以下的函數呼叫方式:

MyMessageBox('程式要結束了喔! 請記得定期備份資料'

Flag = ...);

雖然如此,上述「如果某一個參數開始給預設值,接在後頭的參數也必須用Default Parameters的寫法」這項限制,多少還是可以搭配前一節的Overloading加以彌補:

#0001 function MyMessageBox(Prompt: string;

#0002 Caption: string = '訊息';

#0003 Flag: LongInt = MB_OK + MB_ICONINFORMATION): integer; overload;

#0004 begin

#0005 Result := Application.MessageBox(

#0006 PChar(Prompt)

PChar(Caption)

Flag);

#0007 end;

#0008

#0009 function MyMessageBox(Prompt: string;

#0010 Flag: LongInt;

#0011 Caption: string = '訊息'

#0012 ): integer; overload;

#0013 begin

#0014 Result := Application.MessageBox(

#0015 PChar(Prompt)

PChar(Caption)

Flag);

#0016 end;

#0017

#0018 procedure TForm1.Button1Click(Sender: TObject);

#0019 begin

#0020 MyMessageBox('程式要結束了喔! 請記得定期備份資料');

#0021 MyMessageBox('別說我沒告訴你喔!'

MB_OK);

#0022 end;

(好煩的程式,一再提醒要記得備份。:p)

請幫我注意這次改寫過的程式0009-0012,我重新調整了各參數的次序,並且分別在兩同名函數都加上了overload保留字,這樣,Delphi就知道該呼叫的是哪一個了。

新版本SQL Helper类 C#使用iTextsharp生成PDF 在.NET里用iTextSharp库生成PDF文档 用itextsharp将ASP.NET页面导出到PDF中 什么是JQuery-JQuery API jQuery入门指南-JQuery API jQuery的核心部分-JQuery API $(elements)-JQuery API $(expr, context)-JQuery API $(fn) -JQuery API $(html) -JQuery API $.extend(prop) -JQuery API $.noConflict() -JQuery API each(fn)-JQuery API eq(pos)-JQuery API get(num)-JQuery API get()-JQuery API gt(pos)-JQuery API index(subject)-JQuery API length-JQuery API lt(pos)-JQuery API size()-JQuery API CSS-JQuery API css(key, value)-JQuery API css(name)-JQuery API css(properties)-JQuery API height(val) -JQuery API height()-JQuery API width(val)-JQuery API width()-JQuery API DOM-JQuery API 关于组件ProgID的疑惑: RealPlayer的最新版本是什么? 哪里可以下载? 请教调试问题? 急!我的weblogic的控制台怎么不让进行create操作? 好郁悶啊﹐大家幫幫我﹗ jsp中的select VC中如何打包 在文本中输入,在下拉框中动态显示,大家多帮忙! 寻找算法!! 参与有分了!! 各位大哥,有关软件测试的好书或好的网站能给小妹介绍一下么? 谢谢各位先!! 学习打不起精神.也不刻苦.天天玩,我看我要完蛋了. 软件发布,KindDiary日记软件 PowerBuilder 中Datawindow和Report的本质区别是什么,什么时候该用Report? MEMO字段在SQLSERVER里应为什么类型? 在vc++中client和server端的socket连接断掉了,server端如何能够立刻就知道,而不需server端send的时侯才发觉。 学习c++,到底要看那些方面的书?我现在在看vc++技术内幕,essential c++,effective c++,大家说还应该看什么书? 在VC下使用ODBC绑定时间数据时的问题的解决! 如何动态更改主窗口的菜单? asp编程主题显示,若是汉字则为前15个字,若是字符则前25个,怎么编码?谢谢! 用VBA如何去读服务器上的DOC文档? 一个小而急手的问题 请问哪里有检测IP包的软件? 从网上邻居连接nt时在小窗口中输入用户名和口令的过程如何在程序中实现? 请问:wise的注册吗怎么设置?偶在注册码是不是在第四步--〉对话框--〉注册信息/序列号里,添加了一个编辑文本,但里面就不知道该怎么版了 //牛虻 java applet怎样存取本地文件?我没有更多的分,但我尽己所能 请问:怎么用java执行web页中的javascript脚本? 请问:如何给分?急! 调用动态链结库的错误(BCB调VC的动态链结库)! 兄弟们,ExpressBars 4.1 那里有下的。 请问连接adoconnection的问题? 请大家谈谈自己的学习经验!!现在很多技术,很多书,有些人说:你应该看什么什么书,说了一大堆。我都晕了,不知道自己应该掌握什么? KindDiary日记软件 我想买一块视频采集卡,可否给点意见!!!!! 如何获得对话框中莫个控件地句柄 奇文共欣赏,帐号封存,6个月后再见! WIN200 SERVER中做WIN98无盘工作站的方法? 大虾,请问??? 怎样让一个确定表和一个非确定表建立联系? TC下gettext()的用法问题! 怎样使程序最小化时放到右下角去? 在编辑状态下,将DBGrid记录行内容拖到TreeView节点中去,急? 请教各位怎样使用netbeui协议实现Chat功能 小弟是初学ASP,在想自学的愿头下,不知道从何下手,装了PWS软件解释不了ASP代码。赐教! 短信二次开发包 for 诺基亚,感兴趣者请进。。。。 通过MCSD的考试是多看教材呢,还是多做习题库?我还听说多看MSDN也很有帮助. 给几封VC学习的好文章!自己写的最好! 在数据库中追加字段,网络版和单机版有何不同 override与overload的区别? 网络构架 如何在窗体中使用GIF画? main(String[] args)args传的是什么参,请举例说明 一根长方体的木料,长5m.把它锯成两段后,表面积增加24平方分米.原来这根木料得体积是多少 某项工作,甲单独做4天完成,乙单独做6天完成,若甲先做一天,然后甲乙共同完成此项工作……某项工作,甲单独做4天完成,乙单独做6天完成,若甲先做一天,然后甲乙共同完成此项工作,若甲一共做 一工作,甲单独完成需要15天,乙需要12天.现在甲先单独做一天,接着乙单独做四天,剩下的工作由甲乙二人合作.问剩下的工作两人合作多少天可以完成全部?列方程,说明原因 电机的输出转矩,负载转矩,电磁转矩关系 电导率单位Ms/cm,10s 与μs/cm如何换算 1kgf=多少N 电动机的转矩, 银行卡定活两便存款能从自动取款机取款吗?其实现在网上银行和手机银行都挺方便的是不是卡里可以不留有活期,用的时候再转是不是就行了?平时存定期是不是还多得点利息. 谁知道1kgf=多少N 0.65平方千米和650公顷谁大? 试说明电动机负载改变时,其电磁转矩和电枢电流变化的过程 ? 比10千克少2/5千克是多少千克,多少元增加30%后是52元. 1+1等于……多少 cm 28x+25=33x 怎么运算?请说明基本原理及其公式好吗谢谢 一个密度为0.5×10的三次方千克每立方米,边长为0.2米的实心正方体放置在水平地面上,则该物体的质量是多少千克?它对地面的压力大小是多少牛?对地面的压强是多少帕?(g取10N每千克) 1-m不等于0,那m等于多少? 36千克比多少千克少10% 边长为0.2米的实心正方体,密度为0.1乘10的3次方,质量为多少 一根长1.5m的长方体木料,底面是正方形,把木料锯成两段后,表面积增加了0.18dm2.求来木料的表面积是多少? 谢谢要公式怎么算公式怎么求 谢谢 36千克比多少少3/5 边长为10厘米的实心正方体它的密度为0.6乘以十的三次方静止在装有足量水的容器,且上下底面与水平面平行求木块的体积,水对木块底下的压强求木块在水中的体积,和水对木块底下的压强 一根长方体木料锯成长1.5m的4个长方体,表面积增加了240平方分米.原来这根木料的体积是多少立方米? 比36千克少4分之3是多少千克 1.一项工程,甲做需8天完成,乙做需10天完成.甲的工作效率比乙的工作效率高百分之几? 一项工程,如果甲队独做10天完成,如果乙队独做5天能完成这项工程的三分之一,现在两队合作几天完成?算式 某项工作甲单独做4天完成,乙单独做6天完成.某项工作甲单独做4天完成,乙单独做6天完成,若甲先干一天,剩余的由甲、乙两人合做,问完成此项工程时甲一共做了多少小时? 江森有8000元钱如果按整存整取存入5年5年后它可以从银行里支取多少钱?如果按定活两便存入5年相比整存整取他要少得多少利息?速度我我我我我我我急!11!11111!1a1快1!整存整取3.60百分之定活两 已知滚珠丝杠的参数和负载,如何选择伺服或计算扭矩?滚珠丝杠M25,负载250KG左右,电机转速大概为10rpm/min. 应用题 某项工作甲独做需要4天完成,乙单独做要6天完成,若甲先做1天,然后甲乙共同完成此项工作.,甲一共做了多少天?解题时要把为什么这么做的原因分析下来 20千克比()千克少20% 已知电机转矩如何计算能得知带动的负载的重量 一件工作,甲单独做需4天完成,乙单独做需6天完成,若乙先做两天,再甲单独做,还需要几天列出算式,在写以下意思 2008年12月30日存定活两便5000元,2009.3月31日取,利息是多少 已知电机与滚珠丝杠参数,如何计算推力?1.电机扭矩:35NM,额定转速1500转2.丝杠螺距10mm,直径80.如何得到在丝杠端产生的推力.一位教授要我按照F = 2* M /(d*tan(A+B)) [M:力矩,D2丝杆中径,A为螺蚊升角,B 一件工作,甲和乙合作需四天完成,甲单独做六天完成,乙单独做()天完成. 20千克比()少20%急 滚珠丝杠扭矩计算现已知滚珠丝杠的基本额定负荷Ca与C0a,想知道其最大额定转矩是多少 某项工作甲独做需要4天完成,乙单独做要6天完成,若甲先做1天,然后甲乙共同完成此项工作,若设甲一共做了X天,则所列方程为? 一个物体重49N,体积为5x10负五次方m³,把它放入水中静止时收到的浮力是 请问已算出步进电机带动滚珠丝杠上的负载所需8.5kgf.cm力,那么选多大扭矩的步进电机比较合适怎么算的?最好有公式和例子哦,我是说用多少牛米的步进电机哦 什么是定活两便? 测得苹果浸入水中的体积为1.2×10-4次方m³,求苹果受到的浮力大小?g=10n/kg 根7.2m长的长方体木料,平均锯成3段,表面积增加24平方dm,这木料体积是多少立方米 负载转矩怎么计算 换算;7.3m=几cm=几微米=几纳米 12m/s=几km/h=几m/min 一根2m长的长方体木料,平均锯成3段,表面积增加24平方dm,这木料体积是多少立方米 比10千克的5分之4少5分之4千克的是( ) 明明家有二万元钱想存五年定期,现在五年期整存整取定期存款的年利率为3.60%五年后,实际取回的本息时多少元 请用一句话简单概括?请说明基本原理及其公式好吗谢谢 80千克比64千克重%之几4米比10米短%之几 2011年3月1日存人1万元定活两便存款,于2011年8月4号,2011年9月15号和2012年6月16号取出分别能得多少利息3个月利率为3.33% 半年为3.78% 一年为4.14% 最好要有过程 请问1又1/8=9/(),像这种算法是通分,还是约分,怎样运算?请说明基本原理及其公式好吗谢谢 定活两便是什么意思? 1mm等于多少cm? 做一项工作,甲用五天完成,乙用四天完成,甲每天可完成这项工作的几分之几 某项工作甲独做需要4天完成,乙单独做要6天完成,若甲先做1天,然后甲乙共同完成此项工作,问甲一共做了多少请把解题过程分析出来 银行规定定活两便存款按同档次定期存款利率打六折计算,现有定活两便存款4000元,存了六个月,而定期存款六个月的月利率为0.1725%,那么这项定活两便存款可得本利和多少元?若到期时,所的利 一根长方体的木料长1.5m,把这根木料锯成两段,表面积比原来增加了32平方分米,原来这恨木料的体积是多少立方分米?列式计算, 某项工作甲单独做需要4天完成,乙单独做需要6天完成,若甲先做1天,然后甲乙共同某项工作甲单独做需要4天完成,乙单独做需要6天完成,若甲先做1天,然后甲乙共同完成此项工作,设甲共做 一件工作,甲单独做需要15天完成,乙单独做需要12天完成,现在甲先单独做1天,接着已有单独做4天,剩下的工作由甲乙两人合作,问合作多少天可以完成全部工作任务(一元一次方程,最好给解释)
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn