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

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就知道該呼叫的是哪一個了。

Android Picture和PictureDrawable的用处 Android自定义View以及layout属性全攻略 Android通过Intent发送电子邮件含附件 Android调试技巧之Eclipse行号和Logcat Android Txt文本读写类源代码 Android游戏开发之旅20 双按事件捕获 Android游戏开发之旅19 分辨率大全 保护你的Android付费软件-LVL全攻略(二) 保护你的Android付费软件-LVL全攻略 android调试工具monkey压力测试实战 Android开发工具-App Inventor Android游戏开发之旅18 SoundPool类 Android多线程下载远程图片 Android读写Txt文本文件代码 Android游戏开发之旅17 图像渐变特效 Android游戏开发之旅16 异步音乐播放 Android游戏开发之旅15 按键中断处理 Android游戏开发之旅14 游戏开发实战一 Android游戏开发之旅13 Sensor感应示例 Android游戏开发之旅12 Sensor重力感应 Android游戏开发之旅11 View中手势识别 Android游戏开发之旅十 位图旋转 Android游戏开发之旅九 VideoView类剖析 Android游戏开发之旅八 SurfaceView类实例 Android游戏开发之旅七 自定义SurfaceView Android游戏开发之旅六 自定义View Android游戏开发之旅五 Path和Typeface Android游戏开发之旅四 Canvas和Paint实例 Android游戏开发之旅三 View类详解 Android游戏开发之旅二 View和SurfaceView Android游戏开发之旅一 长按Button原理 请教一小问题? DataSet.AcceptChanges()这个有什么用呀??? 欢迎参加微软新闻组 & Diyinside Windows User Group离线技术沙龙 ?怎样在ASPX的WEB服务中运用C#的线程 在2003下用Interdev 串口通信的问题 紧急50分 在 vb.net 中,如何读取 xml 文件? 斑竹地进来! 欢迎参加微软新闻组 & Diyinside Windows User Group离线技术沙龙 新装的WIN2000,关了启动程序,占内存近100M,还老出怪问题 连编以后,出现的错误,求解 我有一个外来控件(条形码),请问该如何用代码在图片框中动态添加一控件?? 系统设计师就要开考了,请考过高程和就要考高程全部看过来~~~~ 欢迎参加微软新闻组 & Diyinside Windows User Group离线技术沙龙 如何把一组CLASS文件打成一个JAR的包 谁用过solid数据库阿,可知里面怎莫用视图阿??紧急! 求求大哥们了 怎样动态改变控件的属性? 明天要去九城面试,有知道内情的吗,给说说,无限感激,, 大家帮忙看看!我有记个问题一直困扰我!(送分的问题(可以加100分啊),不够可加啊!都是送分题,来者都有分) 欢迎参加微软新闻组 & Diyinside Windows User Group离线技术沙龙 如何处理让播放器播放多首歌 【请教】vc适合oo开发? Window中的大/小字体显示属性改变后,影响对话框大小的问题(VC)? 如何处理让播放器播放多首歌 如何同时使用两个msn 欢迎参加微软新闻组 & Diyinside Windows User Group离线技术沙龙 在线等待大虾求助:win2000缠人问题 求ASP下进度条源码!多谢了! ———请帮忙----! 如何用sql语句将文本文件转换成sql数据库 用什么开发工具最好 急急急!急急急!accept 后如何获取Client端socket的源IP地址字符串???? 欢迎参加微软新闻组 & Diyinside Windows User Group离线技术沙龙 Jbuilder9加载了db2驱动却不能使用 高分请教!!!关于访问数据库的用的DataSet对象的 请问如何传递一个VarChar类型的参数给存储过程? 来Networkers, 感受最强劲的网络力量 关于打印图片的问题,高分~~ 电脑是windows2000和rh linux8双系统,开机时可以选择win还是linux,不选的话默认进linux,现在我想默入win2000,不知如何做? 扩展名为.MSI的是什么文件,怎么用? 明天要去九城面试,有知道内情的吗,给说说,无限感激,, 求中程和高程的书 提问—— 请问MAPI中的ID对应WEBDAV中的哪个字段? 为什么不能安装软件 怎样让窗体从屏幕的右下角显示 ■■高分请教一个SQL语句:ORACLE数据库,请看叙述■■ 请教哦~~我实在不知道该怎么做了。sql当中创建表后是如何修改表格的 Jbuilder9加载了db2驱动成功后却不能使用 quattro什么意思 quattro.这个是什么意思.奥迪汽车才有的,具体是什么意思呢? 跪求慎小嶷《十天突破雅思口语/写作剑8版》MP3 完整版 我把光盘弄丢了.784737819@qq.com~~~xiexie!!! 英语翻译 初中物理电压表测的是电源的电压吗 狡兔有三窟,仅得免于死耳,于是什么用法还有,齐其闻之矣,的其什么用法急,快 左耳里吧啦死前对小耳朵究竟说的是什么 六年级上册英语第六单元A let's try 见异思迁中的通假字,快. 君子生非异也 通假字是什么其意思是什么 奥迪的“quattro”是什么意思? 日本明仁天皇夫妇将首次访印 前首相森学生用400年前地图合成3D游戏 重强风暴袭击欧洲多国 致海陆空交通全部尼泊尔大选首次准许“第三性”公民拥有网友质疑延迟退休因养老金缺口 南京人索马里政府称无人机击毙“青年党”高级韩国有望于2015年实现医生对患者远法国女婴在后备箱被发现 躺在排泄物中英作家曝希特勒逃亡阿根廷活到73岁英国国家打击犯罪局欲聘400名赛博情当代日本大学生校园生活大调查“西非第一舰”长歌当哭,为30万遇难同胞招魂省级机关住房公积金创新驱动 智汇扬州■ 特邀嘉宾简介国家公祭新闻行动走进南农联手打造示范性“智慧城市”肖国栋在英国兼职当保姆 给队友煲汤做坐拥69套房,有何“苦衷”家庭农场143个20名“金牌导游”王爷,动我妈咪试试!穿越之桃花满天飞亿万总裁:前妻,再嫁我一次!撒旦哥哥疼疼我挽清剑凌虚空异世之极品天才至尊狂少幸福原来很简单天价前妻花都特工三星堆遗址旅游石路旅游青浦城隍庙旅游美术馆旅游南京图书馆旅游1912街区旅游南京大学旅游先锋书店旅游瞻园旅游西夏风情园旅游白云山旅游
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘