例子1:Delphi中使用纯正的面向对象方法(这个例子最直接)

Delphi的VCL技术使很多程序员能够非常快速的入门:程序员门只要简单的拖动再加上少量的几个Pascal语句,呵呵,一个可以运行得非常良好的Delphi程序!恭喜你,你已经可以进行程序开发这个伟大的事业了。不过,当你学了一段时间后也许就不这么想了哦。因为Delphi是支持面向对象的语言,其实所有的VCL Component都是基于面向对象的语言设计的,那么当我们用这些面向对象的东东来设计出一些不怎么面向对象的东东好象有些不伦不类的感觉,当然,这里不讨论用不用面向对象方法的好坏,也不想引起相关人士的抗议,毕竟“萝卜青菜”嘛。
  在Delphi中,所有的控件都声明在Publish的关键字下,这也是利用组件编程的默认位置。这样,如果一个Form2想要引Form1(假如其为Unit1)中的某个控件时,只要Use Unit1就OK了,如果Form1要引用Form2的东东,也可以如法泡制。不过,如果哪天我不小心把Form2中的控件改了名,那岂不是Form1中调的的代码全部要重写了么?所以,我主张把这些控件作为Form类的专用元素,外部窗体可以通过Form类公布的属性来访问其中的控件。
   比如:

TForm1=class(Tform)
privte
Button1:Tbutton
end;

不过,这样的设计是解决了成员的高度封装不过,编译会出现错误说Tbutton类找不到,原因是我们把Button1放到了Private中,Delphi不会自动帮我们注册Tbutton类,其实解决这个问题也很简单只要在

Initialization
中加入 RegisterClasses([Tbutton])
就OK了,当然如果有不同的类的控件都可以如法炮制放在RegisterClasses的参数中,因为其参数是一个控件数组。
   当然,这样的面向对象的设计方法是要比以前那种“拖拉”的方法复杂,不过,我们得到了高度的封装性,我认为值得,各位呢?

参考:
http://www.delphifans.com/infoview/Article_338.html

----------------------------------------------------------------------

原理1:
因为在持久化中,你生成的一个新类的对象,系统并不知道他是如何来的,因此需要你注册!

就好像
CreateWindow 一樣,你需要讓操作系統有這樣一個窗口類才行。
比如說,有一個窗口沒有注冊前你只知道它的類名,你想直接建立窗口的話,通常操作:
getClass(className), 然後通過取得類名直接生成窗口,這個時候你就需要先用RegisterClass
RegisterClasses 說白了,就是循環執行:RegisterClass,直至全部注冊完。

 procedure   TForm1.Button2Click(Sender:   TObject);
var
s:Tmemorystream;
ff:TFrame2;
begin
classes.RegisterClass(TFrame2);
classes.RegisterClass(Tlabel);
classes.RegisterClass(TButton); s:=Tmemorystream.Create ;
try
s.LoadFromFile('a');
ff := TFrame2(TFrame.Create(Self));
ff.Parent :=self;
s.ReadComponent(ff) ;
finally
s.Free;
end;
end;

参考

http://bbs.csdn.net/topics/300016429

----------------------------------------------------------------------

原理2:

类引用。这正是delphi强于c++的一点。
C++中的构造函数不可以是虚的,而delphi中却可以。
当由对象调用构造函数时,不能实现多态.
当由类调用构造函数时,同样不能实现多态
但当由类引用调用构造函数时,就可以实现多态了。
borland真伟大!

http://www.yourdelphi.com/topic_94574_ad00.htm
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1047021

----------------------------------------------------------------------

原理3:

正常的思路是注册一些类,就可以充分利用类的多态性来完成一些功能
你可以在程序运行的第一行代码,注册你所有的窗口类,用类常量
然后,在数据库中保存类名,在程序中根据类名查询类名和类的映射表GetClass
实现可以创建任意的已注册类的对象实例,

不是你说不清除,你说的再清楚,也不可能实现,只能用常量来注册

譬如: 你要根据类名获得类的指针,必须用GetClass,前提是此类已注册
而你获得了类指针,只不过是要注册它,但是,如果你能获得,那么它已经注册了
所以这不是自相矛盾吗?

http://www.yourdelphi.com/topic_61709_7db4_2.htm

----------------------------------------------------------------------

原理4(内部实现):

  你可以去追蹤 RegisterClass 這個函式,實際上 Class 的註冊程序是藉著操作 RegGroups 這個私有變數來達成的,你再看看 Classes 內的 finalization 區段,已經有做釋放的動作。我想有很多 Class 是 Delphi 幫我們執行 Register 的,所以他會在程式結束時進行釋放的工作,因此如果使用者 Register 而未 UnRegister 在程式最後都會一併一起處理。至於你說那 UnRegisterClass 就不需要了,你可以看一下 Help 文件中的最後一行這應該能說明為何需要 UnRegister 這的程序了。
"After unregistering a class, its name can be reused to register another object class."

  如果再深入去了解 RegisterClass 所做的事(FClassList.Add(AClass)),你會發現他是將 forbiddenclass 本身存放在一個 TList 中,這個說明了註冊的動作僅是做一個紀錄,並沒有在系統取得任何資源(TList 自己用的不算喔),舉例來說 TForm 的宣告也需要一些記憶體空間存放 VTable RTTI 等相關資訊,但因為這是由 Delphi 管理的,因此自然不需要我們去擔心。但 TForm.Create (nil) 所實體化的記憶體空間,就必須要由我們自行釋放(有 Owner 的就依任務需求而定囉)。我的意思是 RegisterClass 所註冊的東西本來就是 Delphi 所管理的,在程式結束時會將這些資源釋放掉。所以我覺得你的問題應該不是這兩個程序所造成的。

http://www.delphi-ktop-com-tw.my-hot.com/board.php?cid=30&fid=72&tid=56400

----------------------------------------------------------------------

例子2:只有事先注册的类才能动态生成,否则不行。比如TButton可以,但TEdit就不行。

procedure TForm2.Button1Click(Sender: TObject);
var
myRef: TControlClass;
testControl: TControl;
begin
//返回类型是一个类引用
myRef := TControlClass(Classes.GetClass(edit1.Text)); testControl := TControl(myRef.Create(self));
testControl.Parent := self;
testControl.Top := ;
testControl.Left := ;
testControl.Show;
end; //程序运行时就执行
initialization
//注册类
Classes.RegisterClasses([TIcon, TMemo, TButton,TMemo,TLabel]);
//程序关闭时执行
finalization
//删除注册的类
Classes.UnRegisterClasses([TIcon, TMemo, TButton,TMemo,TLabel]); end.

http://www.cnblogs.com/pengshaomin/archive/2012/02/05/2339136.html

----------------------------------------------------------------------

例子3:万一的例子

http://www.cnblogs.com/del/archive/2008/09/10/1137426.html

----------------------------------------------------------------------

例子4:官方的例子:
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Classes_RegisterClass.html

----------------------------------------------------------------------

其它例子或原理,欢迎补充~

有意思的RTL函数RegisterClass(在持久化中,你生成的一个新类的对象,系统并不知道他是如何来的,因此需要你注册)good的更多相关文章

  1. CAD在网页中绘图,并为新绘的对象写扩展数据和读取扩展数据

    在网页中绘图,并为新绘的对象写扩展数据和读取扩展数据.下面帮助的完整例子,在控件安装目录的 Sample\Ie\iedemo.htm 中. 主要用到函数说明: _DMxDrawX::InsertBlo ...

  2. 一个java源文件中为什么只能有一个public类。

    我们都遇到过一个源文件中有多个java类,但当第一个类使用public修饰时,如果下面还有类使用public修饰,会报错.也就是是说一个java源文件最多只能有一个public类. 当有一个publi ...

  3. 需求:lr需要在一串数字中随机位置插入一个新数字的实现方式

    效果如下: 需要用到sscanf()函数:  从一个字符串中读进与指定格式相符的数据. Action() { ],s2[],s3[]; int n=atoi(lr_eval_string(" ...

  4. Java中BufferedReader到底是一个什么类?

    1.java.io.BufferedReader 和 java.io.BufferedWriter 类各拥有8192字符的缓冲区.当BufferedReader在读取文本文件时,会先尽量从文件中读入字 ...

  5. 每日踩坑 2018-11-26 MVC Razor ActionLink 生成的URL中多生成了一个参数 ?length=n

    RouteConfig 的路由注册如下: routes.MapRoute( name: "Default", url: "{controller}/{action}&qu ...

  6. java中使用反射做一个工具类,来为指定类中的成员变量进行赋值操作,使用与多个类对象的成员变量的赋值。

    //------------------------------------------------我是代码的分割线 // 首选是一个工具类,在该工具类里面,定义了一个方法,public void s ...

  7. 给MySQL中某表增加一个新字段,设为主键值为自动增长。

    alter table test_tb  add ID int(10) primary key AUTO_INCREMENT; 设定完成后,原有记录的该字段会增加并自动设上值.以后的值会在已有记录的最 ...

  8. 今天代码中接触到了一个新的东西。js的上下自动滚动,无缝对接。

    js的上下自动滚动,无缝对接.为什么会用到这个东西呢?因为我在做公司的官网项目的修改的时候.有一个产品介绍的页面,会有很多的产品出现在,中间部分的列表里.但是又不能够使用分页.所以我就在想如果,列表数 ...

  9. vue中使用router打开一个新的窗口

    一个单页应用打开一个新的窗口不是很好控制,比如权限的处理,因为原先的页面不会自动刷新,方法很简单: let routeData = this.$router.resolve({ name: " ...

随机推荐

  1. Java随机数使用

    JAVA取随机数的三种方式: Math.random() System.currentTimeMillis() random.nextInt() 废话不多说,看代码: /** *取单个随机数 *Mat ...

  2. ffmpeg处理网络流

    最近遇到好几个人在问ffmpeg如何处理网络流,刚好前段时间也在做这方面,抽空整理了下,把主要代码发出来,希望对大家有用.为简单处理,我这里只简单介绍UDP接收TS流,其实只要是socket接收的都可 ...

  3. gulp(1) 的使用

    1.安装node.js 2.全局安装gulp.js npm install gulp -g 3.在项目本地根目录再安装(通过黑窗口安装)npm install --save-dev gulp/ 或者 ...

  4. 笔试算法题(15):-1到N中包含1的数字的个数 & 连续和为N的序列

    出题:输入一个整数N,求从1到N这N个整数的十进制表示中‘1’出现的次数: 分析: 从左向右处理string表示的数字:当前数字长度为n,判断最左边一位数字字符: 如果是0,则直接递归下一位: 如果是 ...

  5. Git的入门

    Git的基本介绍: Git:是一个版本控制工具. Github:是非常有名的在线版本管理网站(速度比较慢). Oschina:中国版本的github,(旗下的的码云地址:gitee.com,速度快) ...

  6. 我能考虑到的数组(老)方法就这些了(es5)

    代码注释都写的很清楚了 关键字:斐波那契数组.二维数组.多维数组(矩阵)... <!DOCTYPE html> <html lang="en"> <h ...

  7. mysql查询排名

    student_work表 student_info表 sql语句:按grade从高到低排名 结果:

  8. 集训第五周动态规划 C题 编辑距离

    Description Let x and y be two strings over some finite alphabet A. We would like to transform x int ...

  9. sql server 数据库 杀掉死锁进程

    use mastergo--检索死锁进程select spid, blocked, loginame, last_batch, status, cmd, hostname, program_namef ...

  10. loadrunner-3个难点

    1.loadrunner 监控windows资源 2.loadrunner如何实现如下: 1.1.1.1 场景一 10进程同时新增用户 测试场景说明:10进程新增用户, 第一个进程从1到1000,第二 ...