Blue
Red
Green
Orange
Voilet
Slate
Dark

闹鬼闹鬼 一个类没有create 竟然能部分正常使用???(100分)

W

wddark

Unregistered / Unconfirmed
GUEST, unregistred user!
闹鬼闹鬼 一个类没有create 竟然能部分正常使用?????
用delphi时间也不算短了 ,今天调试的时候遇到一个很有意思的问题,大家一起讨论。
我的开发环境:win2k sp4 ,d6+update2
type
PTestObj=^TTestObj;
TTestObj=class(TStringlist)
public
procedure showmsg(AMsg:string);
end;

showmsg就是showmessage一下 ,都没有什么。

然后请看搞笑的代码
procedure TFrmMain.Button1Click(Sender: TObject);
var
p:pTestObj;
t:TTestObj;
begin
//注意没有t:=TTestObj.create;
t.showmsg('aaa');
//t.text:='aaa'
//暂时去掉这行代码
p:=@t;
showmessage(inttostr(integer(p)));
t.free;//这行会报错
end;
大家可以试试看 如果去掉t.free竟然可以一切正常的执行!
加上t.free反而会报错
p我看到了不是nil也就是说确实是存在这个对象的!
这。。。这是什么道理??
另外原来TTestObj是继承于TObject的,一样不需要create也可以使用!
继承于TStringlist之后如果执行t.text:='aaa'
会报错!本来就应该错,但是 t.showmsg('aaa')还是正常的。
所以我觉得很奇怪,如果解释为delphi的特殊机制会自动create,那么t.text:='aaa'也不应该有错,free更不应该有错
如果解释为根本没有create!那么t.showmsg('aaa');怎么可能正常执行!昏啊昏
各位说说看是怎么回事啊
代码:
 
B

blue_morning

Unregistered / Unconfirmed
GUEST, unregistred user!
简单的说,Delphi并没有自动的Create对象。
一个类的存在包含两种情况:
一、类的说明、如以T***开头的类的类型声明,用于说明类的结构。
二、类的实例,如以 variable: T****
variable := T***.Create(owner);中的Variable

类的说明在程序创建时也进行了创建,这就是你看到的P不为空的原因。它指向的是类的说明所在的地址。

类的实例的成员函数实际上是指向类的说明中的成员函数的入口地址指针,就是这么回事。

再看如下的代码:
var
t: TTestObj;
begin
t := TTestObj.Create;
t.Free;
t.showmsg('I was freed');
end;

是不是也是闹鬼了呢? :)

如果你还要问为什么要创建类的说明,那么它是用于实现VMT的。
VMT是什么请自己看一下Delphi高手突破吧。
 
P

pzoon

Unregistered / Unconfirmed
GUEST, unregistred user!
那吗你看看CB里的this-->后面是什么呢[2个--]
出来的东西是不是也闹鬼了[:D]
 
D

DouZheng

Unregistered / Unconfirmed
GUEST, unregistred user!
Re:wddark,
并没有创建TTestObj的实例,所以 t.Text :='test' 时会出错。
 你只要没有调用实例的成员,所以不会出错。
 
B

beta

Unregistered / Unconfirmed
GUEST, unregistred user!
早就说过 N 遍的问题又拿出来问:)

方法是在代码区的,同一个类的所有实例共用的,不管你是否创建一个类的
实例,方法都是存在的。但是,要是你没有创建实例,就不能用其成员,这
就是为什么可以调用没有用到内部成员的方法,而不能直接(以及间接)访
问其 Text 成员。
 
L

lichdr

Unregistered / Unconfirmed
GUEST, unregistred user!
以前討論過。
只要你用到這個類的方法中沒有調用到實例中的成員,不創建實例不會出錯。
 
Z

zhukewen

Unregistered / Unconfirmed
GUEST, unregistred user!
有意思吗?好玩吗?[:(!]
 
Y

yanyandt2

Unregistered / Unconfirmed
GUEST, unregistred user!
鬼啊!!!!!!!!!
 
C

chshanghai

Unregistered / Unconfirmed
GUEST, unregistred user!

楼主, 借个地
(A)
form1=tform1.create(self)
try
if form1.showmodal=id_ok begin
showmessage(form1.textbox1.text);
end;
finally
form1.free
end;

与 (B)
form1=tform1.create(self)
if form1.showmodal=id_ok begin
showmessage(form1.textbox1.text);
end;

有什么区别。  究竟用那段好 我感觉没有什么区别
 
W

wddark

Unregistered / Unconfirmed
GUEST, unregistred user!
谢谢谢谢[:)]
明白了,一直以为类的定义仅仅是“定义”,多谢以上各位
同时看来我对vmt的理解还有错误的。。赶紧去看书呵呵
但是对于beta,blue_morning兄的说法还是有疑问
按照上面的回答,是否只要是不调用实例成员的普通方法就都可以这样使用
那么类方法了??还有存在的必要吗?
[:D]
 
R

redleaf_wgm

Unregistered / Unconfirmed
GUEST, unregistred user!
是因为继承了TStringList的缘故,因为DELPHI中在继承了一个已有的类,而没有重载其Constructor时,系统会自动使用其祖先的Constructor,即使用了TObject的Create方法,况且在Delphi中除了TObject以外不存在没有祖先的对象,因为一切对象的祖先均是TObject,即使你是以这种方式声明的也一样(TMyClass=Class)。
DELPHI没有鬼,只要自己心中无鬼就行了!
 
W

wddark

Unregistered / Unconfirmed
GUEST, unregistred user!
redleaf_wgm兄,代码里面根本没有create哦
呵呵
chshanghai兄
我还是习惯第一种,觉得踏实:)
 
B

blue_morning

Unregistered / Unconfirmed
GUEST, unregistred user!
这个问题beta的回答更实质一些。分应当反过来。 :)

to
:chshanghai

当然是第一段,你创建的没有被释放。如果不理解,可以如下体验:
var
form1: Tform1
begin
for i := 0 to 1000 do
begin
form1=tform1.create(self)
if form1.showmodal=id_ok begin
showmessage(form1.textbox1.text)

end;
然后在Windows的任务管理器中看看这个程序吃了多少内存。
end;
 

Similar threads

顶部 底部