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

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

ShareSDK针对Unity发布社交化组件 2014 CocoaChina开发者大会将公布触控奖学金等高校合作计划 中低端智能手机热销,未来市场或主打价格战 Facebook开源flint:一个用D语言编写的C++静态代码分析器 AMD携手BlueStacks,下半年推出零售版双操作系统 历时6年 Github发布基于Web的桌面文本编辑器:Atom Ratchet:构建移动应用原型,新版支持Android 13个最狂帅炫酷的前沿科技研究项目 打动面试官的五大技能 乐视TV和NBA签约三年互联网电视版权 首度披露大屏运营策略 支撑4.5亿活跃用户的WhatsApp架构概览 免费使用Windows?微软推Windows 8.1 with Bing实验项目 C/C++开发者必不可少的15款编译器+IDE Amazon推荐,Facebook追踪,大数据时代的“狗仔队” NewSQL登场,NuoDB告诉你未来数据库什么样 2014 Unity亚洲开发者大会·中国站:技术课程全面解析 与其坐以待毙不如主动出击 软件如何避免惨遭淘汰 一周消息树:程序员想找好工作?那就学好Linux! 移动周报:开发者必须了解的10大跨平台工具 一周热点:领先Google 150年的数据可视化及WhatsApp架构解析 R语言为Hadoop注入统计血脉 海外游戏市场:Google与“开心农场”谈破局 2014年2月操作系统份额:Windows仍在增长 Win 7以47.31%稳居第一 2014年2月份浏览器份额:IE 8仍全球最受欢迎,Firefox跌破18%大关 跨平台2D游戏引擎V-Play:3天开发一款原生游戏 Appery.io:无编程经验,自己也能DIY移动应用 SAP携手Xamarin和Service2Media 提供移动应用开发框架 8个超实用的jQuery技巧攻略 美国国防部战略:大规模、分布式,构建数字化防御体系 针对小白的Python入门教程——Python使用说明书 耗资460亿美元,天价Olympic上广受诟病的监控和4G 怎样将页面中下拉框的内容与数据库某列关联 请问广州市的朋友,哪儿有旺盛的二手电脑市场? 怎样在VB里用代码设置ACCESS数据库密码 为什么【select * from Topics [OrderBy 发表时间 desc]】和【...[OrderBy 发表时间 desc]】效果一样? 用SUN WTK2.0开发的程序在Nokia模拟器下可编译不可运行,请教 第一个不头晕者接分 杭州工作难找!!!! 如何修改tomcat 4.1.18的配置,使修改过的Servlet能够及时重新加载! edit的text读取 关于ocx的问题? 怎样将一个文本文件以二进制的形式显示 请大家帮我一下!! 怎么破解Email密码? 国内手机及PDA大都用的是哪个操作系统?Palm? 如何是MEMO中增加一行后光标保持在最后位置? vb.net怎样选定word中表格的某一行? ado+intraweb中如何调用coInitialize? 寻找最恶心的笑话 一些对未来的思索、问题,各位来谈谈 有谁知道用哪款打印机比较好呢? 关于类和接口设计问题 如何能把98 聯入2000 如何做一个后台管理-数据库备份程序 如果我用一个Winsock(index)控件数组。Winsock(1)、Winsock(2)同时调用一个延时函数会出什么问题吗? 已知表中字段ID的值,如何定位到这个字段? 谁知道为什么会出这种错误fatal error C1004: unexpected end of file found 小小问题,也有小小的分,不成敬意。 visio ,rose ,ERwin 他们各自的用途是什么,有什么区别呀? Oracle安装的问题——寻求帮忙!!!! 请问Crystal(水晶)报表如何对TextBox进行动态绑定字段? 如何设定mapx图层的颜色 对汇编的渴望! 谁有Asp做的网站?100分奉上! 都进来看看 vc新兵问函数调用菜鸟问题 紧急求救!!!! 谁有delphi关于ado编程 的资料啊(要详细一点的) TreeView的问题,很实在的问题。 关于在PB上实现错误事件处理!!! 关于组件的停靠 用VB.NET连接数据库老是连不了,快精神分裂了,救命啊! 关于SendMessage(高分相送,紧急) 急!!!高手进! 在查找结果中如果某一字段的值相等,只取出其中一条的问题! squid的安装问题???????????????????? SQL语句问题? 冒昧求救,光驱不能使用,不能boot 我的主机总收到外面发的广告信息? 高分求助急!!! 见鬼了,我添加一个TServerSocket控件,然后编译出现:Declaration terminate incorrectly 有谁知道用哪款打印机比较好呢? 在下列化学变化过程中:X+HCL →Y+ NaOH→Z →X所代表的物质可能是A.CuOB.KOHC.K2OD.SO2 COS 165º=?求过程,结果也行 何以解忧 唯有杜康 作文 HCL与NAOH反应是化学变化,其中的物理变化在哪?书上不是说化学变化一定伴随着物理变化吗? cos-165°怎么求?注意是负的 “何以解忧,唯有杜康”的作者是: 燎麻照读中的“自以少时未开悟,晚更历精,明慧过人.”怎么翻译 为什么cos(-α-π)=-cosα?求具体的解题过程 四选一:长期大量饮酒对人体的哪个脏器损害最严重?A、心脏B、肝脏C、肾脏D、脑 怎样才能保证水源、土壤不会受到粪肥外流液体的污染,做到有机性 热水为什么会让东西变软?马上要用! 长期大量饮酒对身体哪些脏器有损害?容易得什么病? 什么溶液与硫酸铜溶液反应生成二氧化硫 为什么植物遇热会变软?是这样的,我看老妈做饭的时候韭菜在锅里翻炒了一会,就软塌塌的了,求各位大神告知小妹这到底是怎么一回事? 铝合金的Hemlok结构型抽芯铆钉有什么特点? 铷与硫酸铜溶液反应生成so2气体吗 读了文言文《孔子家语》 用一句话概括你的感想《孔子家语·六本》君子慎其处 孔子曰:“吾死之后,则商也日益,赐也日损.”曾子曰:“何谓也?”子曰:“商也好与贤已者处,赐也好说 一瓶煤气多少钱?带瓶子一起买的 已知反应Cu+2H2SO4===SO2↑+CuSO4+2H2O,当在标准情况下已知反应Cu+2H2SO4(浓)===SO2↑+CuSO4+2H2O,当在标准情况下,得到448ml的气体时,求(1)消耗的铜的质量(2)转移电子数 弱电解质为什么在离子反应中不可拆,它不是也有部分电离吗难道它所电离出的那少部分离子就忽略不计了? 甲基丙烷只有一种情况吧?有 2-甲基丙烷 那个2不写行吗? 硫酸钾溶液酸碱度? 细胞的失水与吸水可以用扩散作用解释吗? 2-甲基丙烷中的“2-”是什么意思? 等物质的量浓度等体积的碳酸钾、硫酸钾、氯化氢混合后、PH为什么小于7 怎样确定风向 2 甲基丙烷的二溴代物有几种?三个甲基是不是都一样 鉴别1甲基2溴乙烷,1,1二甲基2溴乙烷,1溴丙烷 用化学方法鉴别,详细点 某地风向如何确定 参与身体全部物质交换的是()参与身体全部物质交换的是() A.体循环B.血液循环另一种为什么不是? 请问氯化亚铁和硫酸铜为什么不发生氧化还原反应?如题…… 文言文 吊者言孙叔敖为楚令伊,一国史民皆来贺.有一老父,衣粗衣,冠白冠,后来吊.孙叔敖正衣冠而出见之,谓老父曰:“楚王不知臣不肖,使臣受史民之垢,人皆来贺,子独来吊,岂有说乎?”父曰: 女孩喝酒对身体有什么严重的伤害 美国同意人体器官的克隆具体是怎么回事非常急, 燎麻照读阅读答案1、解释下列字(“”)“及”觉复读( ) “咸”见申擢( ) “俱”奔江南( ) 必往“祈”借( )2、用自己的话说说刘俊是怎样刻苦读书的.3、“悬梁刺股”“焚 爸爸问他在干什么文言文怎么说主要是在干什么怎么说 求懂的行家看看小叶紫檀真假?珠子直径15mm,若是真的小叶紫檀能值多少钱? 阳光的强弱与物体吸收热有怎样的关系? 溶质与溶剂分别是什么 求懂的行家看看小叶紫檀真假?珠子直径18mm,若是真的小叶紫檀能值多少钱?刚买的 晚上拍的 是真的还是假的 说是老料 阳光的强弱与物体吸收热有什么关系? t℃时,向100g质量分数为20%的氢氧化钠溶液中加入等质量的硫酸溶液,恰好完全反应,并测得反应后溶液的P等于7,然后蒸发掉39.5g水,再冷却到t℃,恰好成为饱和溶液,求:t℃时生成物的溶解度 谁能连续说出 “化肥.化肥.化肥.化肥.哈哈哈 你能连续说吗 物体在吸收阳光的同时是否也吸收热?证据是什么? 用丙烯颜料怎么画出海边岩石的颜色最近在做场景 想在石膏做的岩石上面画出海边岩石上的颜色 来体现出海边的场景.要怎么才能画出海边岩石的颜色 土壤和气候因素是如何影响物质的循环,急例如:水资源的浪费和土地侵蚀,温室效应,它们是如何影响物质循环的? 如果物体热胀冷缩,为什么太阳那么热,却不会变大,充斥整个天空呢?为什么冷寂的悲伤,却占据了世界呢. 动物的古文有多少要多少, 各种溶液的饱和ph值有没有表可查有不同溶液在不同温度下的饱和PH值表吗? 解释为主持,管理的文言实词 文言文古文 生产氮化肥的主要污染是什么 文言文矛与盾这个文言文的起因是什么?发展是什么?结果是什么? 铆钉孔一般多大?单位mm~ 化肥污染知多少? 有什么书值得看的,关于管理,哲理,或古文,还有观念的 铆钉的选择 大小长度 根据什么来的?应如何选择?比如什么时候选择M4 M6的?还有他的长度? 化肥会不会农田污染? 若cos(a-15°)=-1/3则cos(165°+a)=? 镁铝铁混合粉末24克,与足量的盐酸反应,得到的气体体积不可能为A.9.6升B.11.2 升C.22.4升D.29 升 货运大伯看上女老板 对方老公出马救急朴槿惠:日本就历史问题道歉前不与安倍博尔特自爆在北京拒吃中餐 吃了100俄罗斯总统向大连外国语大学校长颁发普“世纪审判”遭闹场 穆尔西高喊“我是俄新反恐法:恐怖分子亲友将“连坐”杭州推广能随时调节亮度的路灯杭州凤起立交两边50个停车泊位取消(桐乡获批旅游综合改革试点 先行先试旅考试在即 韩国学生家长跪拜祈福【高清浙医二院去年有60多个医生因用药不合小猫电话报警致警察破门而入 主人无奈1500幅遭纳粹掠夺画作被发现 价值哥伦比亚一辆巴士坠崖致13死61伤刘结一说中国将积极履行安理会轮值主席2013浙江·杭州国际人才交流与合作周日较强冷空气到来 杭州将进入深秋(杭州正研究建设城市风道 从钱塘江引风习近平鼓励企业加强研发“神医”胡万林牢狱生活曝光 监狱未让习近平“现身”中南大学 大学生欢呼雀维维集团&青云志跨界合作 造星功力又看中国专访:顺如合线粒体活性水 一个长沙一男子扮“阔少” 为面子报假警称长沙一小区200多户漏水 业主维权未超牛!建筑师还原《北京折叠》设定,你听说前方有“哨卡”,大货司机集体躲进浙江健促会会长朱耀传:健康产业正成为日本签证更新有望开通网络申请美专家前瞻G20峰会关注点:包容、改山西:2015年来对28名厅级领导干福建:少女遭村主任强奸喝下“百草枯”南京小学新生入学江苏13市书记市长动态:重视县级\"组图:福建“公车第一拍”首辆拍出7.陕西横山县发生山体崩塌地质灾害致1人福建:一官员违纪被免不到1年违规转任惊现成都版“大裤衩” 网友戏称“直筒济宁市各中小学开门迎新生韩联社:韩政府称朝鲜内阁副总理金勇进中国国际矿业装备与技术展览会在泰安开小目标系列之NBA巨星版,多数深藏功
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘