1。书中52页提到,Application.CreateForm的代码如下:
procedure TApplication.CreateForm(InstanceClass:TComponentClass;var Reference);
var
Instance:TComponent;
begin
Instance:=TComponent(InstanceClass.NewInstance);
TComponent(Reference):=Instance;
try
Instance.Create(self);
except
TComponent(Reference):=nil;
raise;
end;
...
end;
这个问题和本书关系不大,只是在书上看到想起来了,这段代码我觉得用如下的写法效果也是一样的:
begin
try
TComonent(Reference):=InstanceClass.Create();
except
Reference:=nil;
raise;
end;
end;
原始代码先用NewInstance方法申请内存,再用Create方法进行初始化,并且如果Create过程中产生异常,则置Reference为空。
我觉得我写的代码也可以达到这样的效果,所以想问一下它们到底有什么区别,我想Delphi中原始的写法总是由它的道理的
procedure TApplication.CreateForm(InstanceClass:TComponentClass;var Reference);
var
Instance:TComponent;
begin
Instance:=TComponent(InstanceClass.NewInstance);
TComponent(Reference):=Instance;
try
Instance.Create(self);
except
TComponent(Reference):=nil;
raise;
end;
...
end;
这个问题和本书关系不大,只是在书上看到想起来了,这段代码我觉得用如下的写法效果也是一样的:
begin
try
TComonent(Reference):=InstanceClass.Create();
except
Reference:=nil;
raise;
end;
end;
原始代码先用NewInstance方法申请内存,再用Create方法进行初始化,并且如果Create过程中产生异常,则置Reference为空。
我觉得我写的代码也可以达到这样的效果,所以想问一下它们到底有什么区别,我想Delphi中原始的写法总是由它的道理的
解决方案 »
- Delphi 读取Excel多个表
- 请问TRegExpr中如何写IP地址的正则表达式?
- FreeAndNil源码请教
- 奇怪
- 如何放大bmp图象,而又不失真,答得好的有50分
- 在客户服务器系统中如何向服务器中请求查询数据?
- 求能显示会计科目的DBTreeView构件(带源码100分,不带源码的50分)
- 白送100分的问题,找一个控件。。。来者有分!
- 高分咨询::请问在哪里可以下到那像OICQ一样酷的控件!!??难道真的没有人知道吗??一定送高分的!!!!
- 有关用DELPHI开发B/S的问题
- ◎◎◎★★★●○●○●○【 散分(2) 】○●○●○●★★★◎◎◎
- 杭州哪里有买李维的<inside vcl>的?有谁知道吗?
书上65页左右提到“一旦使用重载方法之后,那么编译器便会以对象变量声明的类型作为邦定的依据,而不是执行期以对象变量的实际内容为准”,对此我写了一段简单的测试程序:
TBase = class (TObject)
protected
function Fun():String;overload;virtual;
end; TDerived = class(TBase)
protected
function Fun():String;overload;
end;function TBase.Fun():String;
begin
Form1.Memo1.Lines.Add('TBase.Fun()');
Result:='hello';
end;function TDerived.Fun():String;
begin
Form1.Memo1.Lines.Add('TDerived.Fun()');
Result:='hello';
end;procedure TForm1.Button1Click(Sender: TObject);
var
o:TBase;
begin
o:=TDerived.Create();
try
o.Fun();
finally
o.Free;
end;
end;此时调用Button1Click后,确实调用了TBase.Fun()函数,但是如果将以上类声明中的overload关键字都去掉,再与性程序,答案还是这样,
TBase = class (TObject)
protected
function Fun():String;virtual;
end; TDerived = class(TBase)
protected
function Fun():String;
end;
我认为:没有调用TDerived中的Fun函数,只是因为它没有override中的同名函数,而和overload关键字无关,不知道各位大虾是怎么认为的??
o变量声明为Base类型,
o.Fun调用的自然是虚函数,也就是Derived从Base中继承的Fun(),又由于Derived并没有override Base的Func(),所以最终实际调用的还是Base.Func(),这是很自然的
这和重不重名实际上没有关系,和overload也没有关系
按老兄的说法,还有一种写法更简洁procedure TApplication.CreateForm(InstanceClass:TComponentClass;var Reference);
var
Instance:TComponent;
begin
Instance := InstanceClass.Create(Self);
TComponent(Reference) := Instance; ...
end;
>>Instance调用的普通方法了,它已经不再是构造函数
我的观察是这样的,构造函数比普通类对象函数多一个隐含的参数,这个隐含参数是DL参数
我叫它construction_flag, 它实际上是一个枚举类型,
当
CF_INITED_AND_WANT_SEH = -1 (< 0)
时,表示实例已经初始化,但是需要一个SEH框架来确保构造期间发生异常时能够释放实例
对应于Instance.Create的情形CF_INITED_AND_DONT_WANT_SEH = 0
表示实例已初始化且无需SEH,通常是忽略对_ClassCreate的调用,这种情况我没看过CF_UNINITED_AND_WANT_SEH = 1 (> 0)
表示实例尚未初始化且需SEH,对应于InstanceClass.Create的情形这个参数由编译器根据上下文来(到底是类调用的,还是对象调用的)插入一句代码来初始化
如mov dl, 1或者mov dl, -1所以我觉得,Instance.Create(Self)调用的仍然是构造函数,只不过参数不同而已。因为构造函数除了初始化实例以外,还执行构造SEH的工作,
也就是说Instance.Create不单纯是调用Create里面的代码,它还嵌入了一个SEH
Instance.Create
实际上等于
try
Instance.AnyProcessInCreate;
...
except
Instance.Free;
raise;
end;
这一点可以从_ClassCreate函数中看出来不过以前有个贴子曾经讨论过_ClassCreate,好像是一个叫烧鸡翅开的贴,提到一个
Instance2 := Instance1.Create(...);
不能正常工作的问题,因为Instance1.Create不会分配实例,所以不能正确工作所以在这一点上Instance.Create和InstanceClass.Create有所不同
而且
Instance := InstanceClass(InstanceClass.NewInstance);
Instance.Create(...);
的形式比较高级,因为我们可以在Create以前执行一些特殊的操作比如Delphi的IDE也许是这样干的:Comp := TAnyCompClass(TAnyCompClass.NewInstance);
Comp.ComponentState := Comp.ComponentState + [csDesigning];
Comp.Create(FormOrDataModule);但是,不管怎么说,我还是没看出,这里的Instance := InstanceClass(InstanceClass.NewInstance);
Instance.Create(...);和Instance := InstanceClass.Create(...);有什么不同