难道对象不需创建就可以使用?或是Delphi的Bug?????(50分)

H

hotplum

Unregistered / Unconfirmed
GUEST, unregistred user!
请看下面代码:
//类声明
type
TMyObject=class
private
x:integer;
public
procedure print();
end;
//类使用,下面的代码运行并无错误,是何道理????
procedure TForm1.Button1Click(Sender: TObject);
var
MyObject:TMyObject;
begin
//MyObject:=TMyObject.Create
//该句根本不需要
MyObject.print;
end;


 
你打开 Object.Create就明白了

在Tobject的Create里,其实没有任何代码
constructor TObject.Create;
begin
end;
 
如果你调用成员变量x,你就会完蛋
 
对对对。没有任何代码!你加上就有问题的。
 
下面是TObject.Create的代码
constructor TObject.Create;
begin
end;
关注。

 
是没有代码,但什么道理啊

记得以前有一贴介绍过,哪位知道
 
这个嘛,不是一两句说得清楚,简单的说如果不用成员变量,跟普通函数没有区别
 
在Delphi5技术手册上说其实有代码的,但是Borland隐藏了实现,这就是System.pas的特殊性之一。
 
你是在很简单的程序中这样实现的吧?你试试在复杂一点的程序中看看。
这可能和没有new一个指针就去使用是同一个道理。
 
使用成员变量也没有问题
复杂一点的确实不行,只要使用property 就有问题!
但请精通Delphi语言的前辈赐教!delphi对象创建的秘密!
 
不知道是不是我记错了。我记得以前在DELPHI里,TOBJECT是等于Pointer的。但是现在我
看到的TOBJECT是一个真正的CLASS。这是不是BORLAND的改进?
在C++里,建立一个CLASS就是不需要NEW的,只要声明了类变量,就会自动创建一个对象实例
出来。除非你是使用指针。而现在DELPHI的TOBJECT好象已经不是指针了。
 
不是的,如果没有Create,这个对象其实就是Sender,你试试下面这段代码就知道了!
procedure TForm1.Button1Click(Sender: TObject);
var
ss:TEdit;
begin
ShowMessage(ss.ClassName );
end;
 
>>不知道是不是我记错了。我记得以前在DELPHI里,TOBJECT是等于Pointer的。但是现在我
>>看到的TOBJECT是一个真正的CLASS。这是不是BORLAND的改进?
bkbk,你确实记错了,TObject确实是CLASS,底层依然是指针来实现的,而且和C++不一样,
必须显示的Create才能用,C++底层也是指针来实现的,只不过当你声明的时候,C++会
自动调用构造函数,创建一个实例,语法上用法和变量一样,也就是说,不管是定义为
类变量还是类指针,从底层来看(可以看生成的汇编代码)都使用指针实现的。

>>不是的,如果没有Create,这个对象其实就是Sender,你试试下面这段代码就知道了!
dirk, 你的那段代码说明不了任何问题,由于你的变量ss没有初始化,就可能是任意值
当然可以碰巧是Sender!这和编译器的实现有关,有可能每次都是
 
虽然看起来Tobject.Create没有任何代码,但是它分配了存储空间,
构造了VMT(虚方法表),如果一个类没有任何虚方法,那么它不调用Create也
可以,
但是在delphi中,任何类都是从Tobject继承的。所以都有虚方法。
也就是说,如果进行了任何对成员变量的操作,或者调用了虚方法,
都会产生错误。
 
SS2000:
>>你的那段代码说明不了任何问题,由于你的变量ss没有初始化,就可能是任意值
>>当然可以碰巧是Sender!这和编译器的实现有关,有可能每次都是

你试试就知道,并不是什么碰巧,如果这和编译器的实现有关,且每次都是如此,那我
的说法也没有错:在delphi中,这个没有create的对象其实就是Sender!
 
看看这段代码就知道了!
procedure TForm1.Button1Click(Sender: TObject);
var
ss:TEdit;
begin
ShowMessage(ss.ClassName );
TButton(ss).Caption :='哈哈哈';
end;
 
如果什么的代码仍不能说明什么,那再看看这个,ModalResult属性可是TEdit类没有的:
procedure TForm1.Button1Click(Sender: TObject);
var
ss:TEdit;
begin
ShowMessage(ss.ClassName );
TButton(ss).Caption :='哈哈哈';
TButton(ss).OnClick :=ButtonClick;
TButton(ss).ModalResult :=mrAll;
end;

procedure TForm1.ButtonClick(Sender: TObject);
begin
ShowMessage('我是Button');
ShowMessage(vartostr(TButton(Sender).ModalResult =mrAll));
end;

我说的没有错,delphi就是这么处理的!
 
还不相信?再看这段代码:
procedure TForm1.Button2Click(Sender: TObject);
var
ssa:TEdit;
begin
ShowMessage(vartostr(TCheckBox(ssa).Checked));
TCheckBox(ssa).Caption :='1232413423';
TCheckBox(ssa).Checked :=true;
ShowMessage(vartostr(TCheckBox(ssa).Checked));
end;

这和强制类型转换无关,ssa显然没有被赋上TCheckBox的属性值,因为TButton没有Checked属性!
明白了吗?
 
对象在他的方法被调用时只是作为一个隐含的参数指针传递给该方法,如果在该方法中
不使用对象的其他数据成员应该是没有问题的。
 
也就是self
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
580
import
I
顶部