VCL的重要问题!!! (100分)

  • 主题发起人 主题发起人 ReallyFail
  • 开始时间 开始时间
R

ReallyFail

Unregistered / Unconfirmed
GUEST, unregistred user!
1。突然想起来为什么我们定义的窗体不需要写构造及析构函数,要知道我们的窗体中加入了很多的BUTTON,EDIT之类的控件啊???????

2。我从TForm.create看到TComponent.create为止,就是没看到有遍历并创建components这样的方法
而且TComponent的构造函数居然没有inherited Create(AOwner)这样的语句。而是调用
InsertComponent这个方法,到底DELPHI是怎么创建我们在设计期定义的控件及控件事件的?

3。OWNER属性的威力的真正体现到底在那里呢(或者说OWNER属性为什么有这种威力)?跟TComponent的FComponents(TList)
有多大的关系?????

跟我一样不知道的兄弟帮忙UP一下,知道的大虾为我们讲解一下好吗??谢谢!!
 
UP
来听听
 
1、自己定义的窗体是delphi根据dfm文件自己来create的,所以在上面放的每个控件
都是有实例的。
对比:
var label1 :tlabel;
begin
label1.caption = '';
一定会报错的。

3、真正意义?
我只知道当free一个对象时,能自动free owner为这个对象的所有控件
 
to jianl:
1。小第倒是知道在DFM文件中存有控件的属性定义,但至少在语句上没见到创建控件的
过程啊!
3。我问的是为什么FREE一个对象的时候能将OWNER属性为该对象的类全部都FREE掉!
 
拥有关系和父子关系的区别
 
1。正如jianl所说,编译的时候窗体文件Dfm被当成资源编译到EXE文件中。我们用UltraEdit还可以在
Exe文件中看到Dfm文件的原型。Delphi编译的文件很大就是与此有关。
在执行程序时,构造函数会自动根据该资源创建窗体上的子控件的。
2。构造函数本身就是创建类的实例用的,不用调用祖先的。构造函数比一般函数特殊就在这个地方。
TComponent的祖先根本就没有Create(AOwner);这样的构造函数。他祖先的构造函数没有参数。
而且TComponent不想使用他祖先的Create();当然就不用调用了。
3。Owner当然很有用。不然有很多在局部声明的对象创建完了变量就释放了,那对象岂不是成了死对象。
利用Owner我们可以很方便的找到他们。而且Owner还负责对象的释放,方便了我们的开发。
 
to 楼上的大虾:
1。举个例子:
TMYFORM=class(tform)
edit1:tedit
end;
现在我们以对待一个自定义类的方式来对带TMYFORM时,那这没有构造函数且含有类中类的类
不是很可笑?还是编译器已经根据我们的窗体类定义帮我们写好了构造函数???????

3.我想问的是OWNER属性具有的功能是凭借什么实现的,比如我现在的理解是OWNER之所以能
将他的子类FREE掉是因为每个子类在创建的时候实际调用的是INSERTCOMPONENT这个方法。
而这个方法实际上是将这个子类加入到FCOMPONENT(TLIST)列表中去。而OWNER FREE的时候
只要将FCOMPONENTS中的类全部释放掉就可以了?????不知以上的想法是否正确????
 
1.

2.基本正确:
TComponet.Destroy调用TComponent.DestroyComponents
DestroyComponents释放所有的子对象。
 
1.TCustomForm.Create的过程调用了InitInheritedComponent过程,
仔细看源码,秘密就在那里.
 
谢谢xeen大虾,好几次都是你帮我解答问题的!!谢!
在看了,看得有点晕!
 
我想这就是d和java不同的地方,java才是真正的面对对象吧,所有的对象都是要构造中
创建,不依赖于编译器,也只有这样它才能跨平台就是了,呵呵
 
其实编译器帮你做了好多事,
1是系统帮你create了
2你想问的是这个吗?
for i := 0 to self.componentcount -1 do
showmessage(component.name);
3和一一样,系统帮你做了释放工作,当释放了某个组建之后,系统会释放掉owner为这个组建的所有component。
 
我不是说了么,有什么奇怪的。DFM窗体文件就是资源文件。
 
1。delphi的所有过程都可跟踪,全部在代码中可以看到。
这是工程文件project1.dpr的代码
program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);//看到窗口的创建过程了吗?
Application.Run;
end.
重要提示:Application.Initialize不是程序的第一个执行语句。
因为本单元uses Forms,
Forms.pas有如下代码:
initialization
InitProcs;
RM_TaskBarCreated := RegisterWindowMessage('TaskbarCreated');
Classes.RegisterFindGlobalComponentProc(FindGlobalComponent);
initialization部分会在最先执行
 
知道情况的在给说说,我想把它搞清晰点!等有了个大概就马上给分!
to wr960204
谢谢你的回答,你可能没看明白我的第三个问题,比如:
>>正如jianl所说,编译的时候窗体文件Dfm被当成资源编译到EXE文件中。我们用UltraEdit还可以在
>>Exe文件中看到Dfm文件的原型。Delphi编译的文件很大就是与此有关。
即使被编进了资源文件,那你也得有创建子类的构造函数吧?

>>。Owner当然很有用。不然有很多在局部声明的对象创建完了变量就释放了,那对象岂不是成了死对象。
>> 利用Owner我们可以很方便的找到他们。而且Owner还负责对象的释放,方便了我们的开发。
VCL利用OWNER属性来释放子类,但为什么OWNER能有这个功能呢???你的回答可能更趋向
OWNER的好处!!
 
Owner表示一个对象被谁拥有,拥有者将负责对他的销毁工作
当改变Owner属性,或创建一个对象时传递Owner参数,都会在这个对象的主人那里
进行登记,这是由TComponent类来完成的

每一个从TComponent继承而来的类都会具有这种的特性,
每一个这样的对象,在内部保存了一个列表,登记了所有被它拥有的对象
自己释放前,他会先释放他自己所拥有的所有对象
如果那些子对象也拥有其他的对象,则那些个对象也会以同样的机制被销毁

所以实际上,这是一个嵌套,并递归调用的过程,最终释放被这个对象拥有的任何层次的
子孙对象
 
OWNER能有这个功能呢.
因为TComponent的Owner本身就必须是TComponent。
作为一个组件的Owner你看看TComponent的代码就知道了。
他有一个叫FComponents域。是个TList类型的。
当属于他的对象在构件时,要调用到他的InsertComponent方法。
导致向FComponents添加一个Item指向该对象。
所以在TComponent构件在释放之前他会遍厉并释放FComponents所指向的对象,而且会通知他的拥有者
使用RemoveComponent方法在FComponents中删除自身。
就是这么简单。
 
为什么被放在窗体上的对象,在运行时会被自动创建?

问题的关键在于 published这个关键字的功劳,
背放置在窗体上的对象,其变量出现在窗体类定义的private部分之前,没有任何的修饰
但是,我们在左侧的类浏览器中可以看到他们属于published部分

而放在published部分的变量,在创建对象时,其实际的数值可以从对象资源中得到
对一个对象来说,加载资源的过程会引起创建对象,这是由VCL的底层中,
对象的序列化(streaming)的方法所造成的,由此,才使得可视化的编程成为了可能,
否则,我们一个一个来创建,岂不是很麻烦
 
同意 LiChaoHui
的观点。
 
后退
顶部