菜鸟问题(100分)

  • 主题发起人 主题发起人 Another_eYes
  • 开始时间 开始时间
A

Another_eYes

Unregistered / Unconfirmed
GUEST, unregistred user!
类的方法中能调用free释放自己吗? 有否冲突?
 
应该可以。
就象建一个FORM,在FORM中可以关闭,FREE它一样。
 
若方法不是工作在C/S中,则是可以的。因为你的方法在系统中可能是共用的,
要Free它,你必须有相应的权限才可以。在单机情况下,可以Free,但可能会
出现意想不到的麻烦。
 
我的意思是在自定义类的instance的某个方法中调用free方法释放自己这个instance.
3h:
delphi help中说得明白, form类不要用free释放, 要用release. 不然可能会出问题.
更不必说在类的方法中调用free了.
 
对于这个问题,C++和PASCAL的风格不太一样.

C++认为,只有在对象的作用域结束时由析构函
数释放所有资源,或者由程序员显式调用delete
删除由new生成的对象才是合法的.

PASCAL认为,对象在任何时候都可以释放.对
PASCAL来说,所有对象都相当于C++的用new
生成的对象.

由于VCL是PASCAL编写的,所以应该遵循PASCAL
的风格.也就是说,在能够保证没有别的对象会
删除本对象的情况下,可以调用Free.

这就涉及到别的对象与自己的关系问题.对VCL来
说,某个对象都有一个数组保存了自己拥有的对象,
在自己结束时将一并删除.而每个对象又有个Parent
指针,当自己释放时,会从Parent的数组中将自己清
除.所以,一般来说,不会方式冲突.当然,某些时候
由于其它的原因,这个原则不是被完全遵守的.这些
特殊情况下就不能这样考虑了.
 
本人认为不行,FORM是使用ACTION:=CAFREE来释放本FORM,
在一个类中调用本身的FREE,我看不行.
 
类是不允许调用Free来释放自己的。Form.Free是采取了特殊的处理方法来实现的.
 
huaizhang, 证据呢?

我这到有你观点的反证.
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TTest = class(TEdit)
public
procedure ReleaseSelf(s: String);
end;

var
Form1: TForm1;
tt : TTest;
implementation

{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
tt := ttest.create(form1);
tt.parent := form1;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
randomize;
tt.ReleaseSelf(inttostr(Random(99999)));
end;


procedure TTest.ReleaseSelf(s: String);
begin
Text := s;
application.processmessages;
sleep(2000);
free;
end;

end.

运行40次没出现问题.
 
我想是应该可以调用自己的free的,因为释放一个东西的方法是xxx.free,是其本身
的一个方法,而类内部是可以直接调用其内部方法的。如果释放的方法是free
(xxxx),这样才可能会在本身调用时出错

不好意思,我是业余的,可能对类的理解不深刻
 
也许可以用, 不过心理总觉得不塌实。 如果要出现问题的话可能是在free调用完成之后程序返
回的地址是否有效吧。
 
同意sherman、huizhang
好象自己不能调用自己的 Free,会出现错误:
Project ????.exe raised exception class EAccessViolation with
message 'Access violation at address XXXXXX. Read of address
XXXXXX'.
 
......Read of address XXXXXX ??????
不会吧? 是不是你程序中写错什么了?

比如:
TTest = class(TComponent)
public
procedure FreeSelf;
end;

procedure TTest.FreeSelf;
begin
free.
end;
这段代码算不算自己释放自己?

外界程序调用这段代码和直接调用Free有区别吗?
 
eYes, 按照OO Pascal的语法Object是可以释放自己的, 我前面说的不允许是不对的。
但是带有Onwer属性的控件是不允许自己释放自己的,因为自己释放了自己之后而他的
Owner并不知道,还要到Componts列表中去找这个控件,这时候就会出现 Access
Voilation Error。

 
to huizhang:
有Owner属性的对象也可以释放自己,因为DELPHI的VCL库
的Free函数都是处理了Owner属性的.所以,调用Free释放
是不会出问题的.我在BCB里面总是直接删除我自己动态生
成的控件,从未出过问题.这与控件自己调用Free没有区别.
至于Access Voilation Error,多半是自己的代码在删除
对象之后又引用了它导致的.

其实对象的Free函数必然是自己释放自己,既然Free可以,
对象的其它函数调用Free就没有问题的.
 
lhz: 有道理! 我又详细地看了TComponent的Destroy帮助, Destroy确实发出
opRemove通知给其他相关类, 然后释放自己拥有的Components, 最后他从它的Owner
的Components List中去掉自己. 帮助文件说, 千万不要在自己的事件中释放自己,
看来到此才是我们讨论的最终结果.
 
多人接受答案了。
 
后退
顶部