Delphi中的“委托”
.NET中有委托(Delegate)的概念,其声明形式如下所示:
TMyDelegateFunc = function (AIntParam: integer; AStringParam: string): Boolean;
TMyDelegateProc = procedure (AIntParam: integer; AStringParam: string);
TMyObjectDelegate = procedure (AIntParam: integer; AStringParam: string) of object; //对象的
TMyRegularDelegate = procedure (AIntParam: integer; AStringParam: string); //非对象的(一般的)函数/过程
- {type
- TMyDelegateFunc = function (AIntParam: integer; AStringParam: string): Boolean;
- TMyDelegateProc = procedure (AIntParam: integer; AStringParam: string);
- //在以上的声明中,还可以用of object关键字来规定所定义的“委托”是应用于对象的函数/过程,还是应用于非对象的函数/过程,例:
- type
- TMyObjectDelegate = procedure (AIntParam: integer; AStringParam: string) of object; //对象的函数/过程
- TMyRegularDelegate = procedure (AIntParam: integer; AStringParam: string); //非对象的(一般的)函数/过程
- //以下举个简单的例子来说明一下Delphi中“委托”的应用。附件为完整程序。 }
- unit UnitFrmTest;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls;
- type
- TDelegateType = (dtObject, dtRegular);
- //对象的函数委托
- TObjectNumFuncs = function (const ANumOne: Double;
- const ANumTwo: Double): Double of object;
- //非对象(一般)的函数委托
- TRegularNumFuncs = function (const ANumOne: Double;
- const ANumTwo: Double): Double;
- type
- TfrmTest = class(TForm)
- edtNumOne: TEdit;
- edtNumTwo: TEdit;
- btnAdd: TButton;
- btnSub: TButton;
- btnMultiply: TButton;
- btnDivide: TButton;
- lblResult: TLabel;
- rbObjectDelegate: TRadioButton;
- rbRegularDelegate: TRadioButton;
- procedure rbRegularDelegateClick(Sender: TObject);
- procedure rbObjectDelegateClick(Sender: TObject);
- procedure MyButtonClick(Sender: TObject);
- private
- { Private declarations }
- //指示当前是使用对象的函数,还是非对象的函数
- FDelegateType: TDelegateType;
- { 对象的函数列表 }
- function Add(const ANumOne: Double;
- const ANumTwo: Double): Double;
- function Sub(const ANumOne: Double;
- const ANumTwo: Double): Double;
- function Multiply(const ANumOne: Double;
- const ANumTwo: Double): Double;
- function Divide(const ANumOne: Double;
- const ANumTwo: Double): Double;
- { 对象的函数列表 结束 }
- function DoObjectCalc(const ANumOne: Double;
- const ANumTwo: Double; AMethod: TObjectNumFuncs): Double;
- public
- { Public declarations }
- end;
- { 非对象(一般)的函数列表 }
- function Add(const ANumOne: Double; const ANumTwo: Double): Double;
- function Sub(const ANumOne: Double; const ANumTwo: Double): Double;
- function Multiply(const ANumOne: Double; const ANumTwo: Double): Double;
- function Divide(const ANumOne: Double; const ANumTwo: Double): Double;
- function DoRegularCalc(const ANumOne: Double; const ANumTwo: Double;
- AMethod: TRegularNumFuncs): Double;
- { 非对象(一般)的函数列表 结束 }
- var
- frmTest: TfrmTest;
- implementation
- {$R *.dfm}
- { 非对象(一般)的函数列表 }
- function Add(const ANumOne: Double; const ANumTwo: Double): Double;
- begin
- Result := ANumOne + ANumTwo;
- end;
- function Sub(const ANumOne: Double; const ANumTwo: Double): Double;
- begin
- Result := ANumOne - ANumTwo;
- end;
- function Multiply(const ANumOne: Double; const ANumTwo: Double): Double;
- begin
- Result := ANumOne * ANumTwo;
- end;
- function Divide(const ANumOne: Double; const ANumTwo: Double): Double;
- begin
- try
- Result := ANumOne / ANumTwo;
- except
- on E: EZeroDivide do
- begin
- frmTest.edtNumTwo.SetFocus();
- frmTest.lblResult.Caption := '除数不能为零';
- Abort();
- end;
- end;
- end;
- function DoRegularCalc(const ANumOne: Double; const ANumTwo: Double;
- AMethod: TRegularNumFuncs): Double;
- begin
- Result := AMethod(ANumOne, ANumTwo);
- end;
- { 非对象(一般)的函数列表 结束 }
- { TfrmTest }
- { 对象的函数列表 }
- function TfrmTest.Add(const ANumOne, ANumTwo: Double): Double;
- begin
- Result := ANumOne + ANumTwo;
- end;
- function TfrmTest.Divide(const ANumOne, ANumTwo: Double): Double;
- begin
- try
- Result := ANumOne / ANumTwo;
- except
- on E: EZeroDivide do
- begin
- edtNumTwo.SetFocus();
- lblResult.Caption := '除数不能为零';
- Abort;
- end;
- end;
- end;
- function TfrmTest.DoObjectCalc(const ANumOne, ANumTwo: Double;
- AMethod: TObjectNumFuncs): Double;
- begin
- Result := AMethod(ANumOne, ANumTwo);
- end;
- function TfrmTest.Multiply(const ANumOne, ANumTwo: Double): Double;
- begin
- Result := ANumOne * ANumTwo;
- end;
- procedure TfrmTest.MyButtonClick(Sender: TObject);
- var
- dblNumOne, dblNumTwo, dblResult: Double;
- begin
- if not (Sender is TButton) then Exit;
- dblNumOne := StrToFloatDef(Trim(edtNumOne.Text), 0.0);
- dblNumTwo := StrToFloatDef(Trim(edtNumTwo.Text), 0.0);
- case (Sender as TButton).Tag of
- 0: //加
- begin
- case Self.FDelegateType of
- dtObject:
- begin
- dblResult := Self.DoObjectCalc(dblNumOne, dblNumTwo, Self.Add);
- //若为
- //dblResult := Self.DoObjectCalc(dblNumOne, dblNumTwo, UnitFrmTest.Add);
- //则会提示以下错误:
- //E2009 Incompatible types: 'regular procedure and method pointer'
- end;
- dtRegular:
- begin
- dblResult := DoRegularCalc(dblNumOne, dblNumTwo, UnitFrmTest.Add);
- //若为
- //dblResult := DoRegularCalc(dblNumOne, dblNumTwo, Self.Add);
- //则会提示以下错误:
- //E2009 Incompatible types: 'regular procedure and method pointer'
- end;
- end;
- end;
- 1: //减
- begin
- case Self.FDelegateType of
- dtObject:
- begin
- dblResult := Self.DoObjectCalc(dblNumOne, dblNumTwo, Self.Sub);
- end;
- dtRegular:
- begin
- dblResult := DoRegularCalc(dblNumOne, dblNumTwo, UnitFrmTest.Sub);
- end;
- end;
- end;
- 2: //乘
- begin
- case Self.FDelegateType of
- dtObject:
- begin
- dblResult := Self.DoObjectCalc(dblNumOne, dblNumTwo, Self.Multiply);
- end;
- dtRegular:
- begin
- dblResult := DoRegularCalc(dblNumOne, dblNumTwo, UnitFrmTest.Multiply);
- end;
- end;
- end;
- 3: //除
- begin
- case Self.FDelegateType of
- dtObject:
- begin
- dblResult := Self.DoObjectCalc(dblNumOne, dblNumTwo, Self.Divide);
- end;
- dtRegular:
- begin
- dblResult := DoRegularCalc(dblNumOne, dblNumTwo, UnitFrmTest.Divide);
- end;
- end;
- end;
- end;
- lblResult.Caption := '结果:' + FloatToStr(dblResult);
- end;
- procedure TfrmTest.rbObjectDelegateClick(Sender: TObject);
- begin
- Self.FDelegateType := dtObject;
- end;
- procedure TfrmTest.rbRegularDelegateClick(Sender: TObject);
- begin
- Self.FDelegateType := dtRegular;
- end;
- function TfrmTest.Sub(const ANumOne, ANumTwo: Double): Double;
- begin
- Result := ANumOne - ANumTwo;
- end;
- { 对象的函数列表 结束 }
- end.
http://blog.csdn.net/procedure1984/article/details/3897028
Delphi中的“委托”的更多相关文章
- c++中实现委托
成员函数指针与高性能的C++委托(上篇) 撰文:Don Clugston 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做"闭包(clo ...
- [转]Delphi 中动态链接库(dll)的建立和使用
动态链接库是一个能够被应用程序和其它的DLL调用的过程和函数的集合体,它里面包含的是公共代码或资源.由于DLL代码使用了内存共享技术,在某些地方windows也给了DLL一些更高的权限,因而DLL中可 ...
- delphi中接口的委托和聚合
Delphi的TRegistry注册表类 方法详解 Delphi的接口编程入门 delphi中接口的委托和聚合 2009-09-27 10:44:44| 分类: 默认分类 | 标签: |举报 |字 ...
- Delphi中stringlist分割字符串的用法
Delphi中stringlist分割字符串的用法 TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 1.CommaT ...
- delphi中exit,abort,break,continue 的区别
from:http://www.cnblogs.com/taofengli288/archive/2011/09/05/2167553.html delphi中表示跳出的有break,continue ...
- Delphi中使用比较少的一些语法
本文是为了加强记忆而写,这里写的大多数内容都是在编程的日常工作中使用频率不高的东西,但是又十分重要. ---Murphy 1,构造和析构函数: a,构造函数: 一般基于TComponent组件的派生类 ...
- 如何在 Delphi 中静态链接 SQLite
搞了我几个小时,终于成功在 Delphi 中静态链接了 SQLite (v3.5.4),下一步就是研究加密了,呵呵中间其实遇到很多问题,今天累了,就不说了,改天补上 下载测试工程 下面说说方法 1.当 ...
- 翻箱倒柜,《Delphi中建议使用的语句》
(*//标题:Delphi中建议使用的语句整理:Zswang连接:http://www.csdn.net/Expert/TopicView1.asp?id=724036日期:2002-06-22支持: ...
- delphi中break,continue, exit,abort, halt, runerror的异同
delphi中表示跳出的有break,continue, exit,abort, halt, runerror. 1.break 强制退出循环(只能放在循环中),用于从For语句,while语句或re ...
随机推荐
- HTML5的绘图的支持
一.简单介绍canvas元素 <canvas.../>是HTML5新增的一个元素,该元素用于绘制图形.实际上<canvas../>只是相当于一张画布. 它除了可以指定通用属性外 ...
- 为IE6-7间接支持:before和:after伪类
:before和:after我们经常会用到,特别是在做移动端页面时,利用它制作文字前后的ICON.图片的垂直居中之类的非常方便且代码简洁(当然,功能远比这些要多的多...). 可是在PC端,由于现在还 ...
- video详解 HTML5中的视频:
一.video 视频的方法.属性.事件详解 方法:play() 播放 pause() 暂停 属性:currentTime播放到当前的时间 duration视频的总时长 事件:ended 播放完 ...
- 【LeetCode题意分析&解答】36. Valid Sudoku
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...
- JAVA和.NET互调用
通过接口实现JAVA和.NET互调用-JNInterface 使用C#编程多年,也十分感激微软在语言架构.语法糖.编辑器等方面给自己带来的便利.但因为最近工作中有接触到JAVA,渐渐地发现的确像大家说 ...
- linux杂谈(十七):iscsi存储分离技术
1.iscsi简单介绍 iSCSI利用了TCP/IP的port 860 和 3260 作为沟通的渠道.透过两部计算机之间利用iSCSI的协议来交换SCSI命令,让计算机能够透过快速的局域网集线来 ...
- unity3d插件Daikon Forge GUI 中文教程-5-高级控件listbox和progress bar的使用
(游戏蛮牛首发)大家好我是孙广东.官网提供了专业的视频教程http://www.daikonforge.com/dfgui/tutorials/,只是是在youtube上,要观看是须要FQ的. 只是教 ...
- c/c++测试程序运行时间
算法分析中需要对各种算法进行性能测试,下面介绍两种通用的测试方法,由于只用到标准c语言函数,所以在各种平台和编译器下都能使用. 方法1: clock()函数 开始计时:start = clock() ...
- Linux系统源码安装过程中的prefix选项
在linux和unix环境中,源码安装是最常用的软件安装方式,一些软件除了提供源码外,也提供各种发行版的二进制安装包(如基于redhat包管理工具的rpm包),但强烈建议使用源码安装方式.原因是:(1 ...
- Object-c中@private、@protected、@public解析
Objective-C中,类的实例化变量的范围有@private.@protected.@public.他们代表的意思和C++中相同,只是前面添加了一个@符号.下面介绍一下他们代表的范围: 指令 意思 ...