一个简单问题!但困扰我很久!

WuHeHai 2001-08-01 07:48:57
一个简单的问题:如何来判断一个对象是有效的?
在我调用一个对象的方法时,经常的做法先判断这个对象是否nil或调用Assigned函数。
如:
if btnNew <> nil then //或者if Assigned(btnNew) then
ShowMessage(btnNew.Caption);
但用以上的方法有时会不起效果。如下面这种情况:
btnNew.Free;
if btnNew <> nil then //或者if Assigned(btnNew) then
//下面的代码会产生异常
ShowMessage(btnNew.Caption);
原因是Free后,对象指针并不一定为nil。所以有一个经验性的总结是Free后马上赋值为Nil。
但我现在想知道如何判断一个对象是否有效(在C++中有一个方法AssertValid)。换句话说,不管这个对象是否为nil,只要不能访问这个对象的方法,就返回False。
在此,先谢谢CSDN的兄弟姐妹们!




...全文
225 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
little_f 2001-08-15
  • 打赏
  • 举报
回复
那你试试捕捉这个异常啊,用自己自定义的异常处理函数。我看C++的AssertValid也是这样干的,只不过你看不到异常,程序内部处理了。
WuHeHai 2001-08-15
  • 打赏
  • 举报
回复
多谢MusicWind兄及CSDN兄弟的回答。现在该结帖子了。
musicwind 2001-08-08
  • 打赏
  • 举报
回复
to WuHeHai:
不用RTTI,好像没有办法。
musicwind 2001-08-08
  • 打赏
  • 举报
回复
看看文章呀
musicwind 2001-08-07
  • 打赏
  • 举报
回复
大家看看这篇文章,或许有用:
《探究:Delphi中的对象指针是否可用》
http://www.csdn.net/develop/read_article.asp?id=9508
radar 2001-08-07
  • 打赏
  • 举报
回复
用freeandnil,没问题
tjf1117 2001-08-07
  • 打赏
  • 举报
回复
坚决拥护 prometheusphinx(白日梦) 的方法,
用freeandnil,绝对没有问题,

关于procedure FreeAndNil(var Obj);的帮助
Do not pass a value for Obj if it is not an instance of TObject or one of its descendants.

从帮助看可以,obj参数必须是一个TObject的子类或实例。
WuHeHai 2001-08-07
  • 打赏
  • 举报
回复
UP
  • 打赏
  • 举报
回复
只能使用异常处理.
WuHeHai 2001-08-05
  • 打赏
  • 举报
回复
UP!
WuHeHai 2001-08-04
  • 打赏
  • 举报
回复
是啊,Musicwind,好久没见了,近来可好?
你的第一种解决方案,我试了一下,好象不行。从理论也说不过去。
如果换成frmChild := nil; 倒是可以的。

你的第二种方案,我也想到了,采用异常处理(你那个传的参数类型为TObject更通用一点),但速度有点慢(要访问RTII)。
不知是否有更好的方法。多谢Musicwind及各位兄弟。
musicwind 2001-08-02
  • 打赏
  • 举报
回复
Wu,给分吧,哈哈,好久不见了。
musicwind 2001-08-02
  • 打赏
  • 举报
回复
子窗体的Close事件
procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
Self := nil; //加这么一句,就行了呀
end;

要么这样:
function ComponentExists(AComponent: TComponent): Boolean;
begin
try
AComponent.HasParent;
result := True;
except
result := False;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Component: TComponent;
begin
Component := TComponent.Create(self);
//Obj.Free;
if ComponentExists(Obj) then
showmessage('component ok')
else
showMessage('component err');


end;

关键在于HasParent是TComponent的对象方法,而不是成员方法,所以管用。
musicwind 2001-08-02
  • 打赏
  • 举报
回复
子窗体的Close事件
procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
Self := nil; //加这么一句,就行了呀
end;

要么这样:
function ComponentExists(AComponent: TComponent): Boolean;
begin
try
AComponent.HasParent;
result := True;
except
result := False;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Component: TComponent;
begin
Component := TComponent.Create(self);
//Obj.Free;
if ComponentExists(Obj) then
showmessage('component ok')
else
showMessage('component err');


end;

关键在于HasParent是TComponent的对象方法,而不是成员方法,所以管用。
trainbox 2001-08-02
  • 打赏
  • 举报
回复
自己写一个函数就可以了
prometheusphinx 2001-08-02
  • 打赏
  • 举报
回复
为什么不用FreeAndNil方法呢?
FreeAndNil(obj)等于obj.Free;obj:=nil;
cobi 2001-08-02
  • 打赏
  • 举报
回复
gz
VSaber 2001-08-01
  • 打赏
  • 举报
回复
这个问题我和好多人讨论过了,还没想到好办法!呵呵,所以只好每次delete了就置为nil了
WuHeHai 2001-08-01
  • 打赏
  • 举报
回复
上面例子举得不太好,改到MDI中!
主窗体有一个菜单,创建一个子窗体。
procedure TfrmMain.Button1Click(Sender: TObject);
begin
if not Assigned(frmSecond) then begin
frmSecond := TfrmSecond(Application);
end;
frmSecond.Show;
end;

子窗体的Close事件
procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
第一次可以创建子窗体。但关闭后,就不能再创建子窗体了

WuHeHai 2001-08-01
  • 打赏
  • 举报
回复
原因就是不加一句
btnNew := nil;
有是不能赋值为Nil。
如:打开一个窗体。这个窗体已经存在时,则显示,否则创建。而关闭时是调用Form.Close
具体代码如下:
procedure TfrmFirst.Button1Click(Sender: TObject);
begin
if not Assigned(frmSecond) then begin
frmSecond := TfrmSecond(Application);
end;
frmSecond.Show;
end;

procedure frmSecond.btnClose(Sender: TObject);
begin
Self.Close;
end;
加载更多回复(4)

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧