转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
探究:如何判断Delphi中的对象指针是否可用         ★★★★

探究:如何判断Delphi中的对象指针是否可用

作者:闵涛 文章来源:闵涛的学习笔记 点击数:716 更新时间:2009/4/23 18:44:00

 

 

 

探究:如何判断Delphi中的对象指针是否可用

作者: Musicwind®

创建时间:2001-08-07


 

近日,在网上看到有网友问曰:如何确定一个对象指针是否可用?也就是说,如何确定一个对象指针是否指向一个真正可用的对象实例?其实这本不应该成为一个问题。因为对于程序设计者来说,他应该能够控制自己的程序不去访问一个无效的指针,因为所有的对象实例的创建和销毁都在他控制之下。并且即便没有一个直接的办法来判断对象指针是否可用,也可以通过其他间接的途径(比如使用一些标识等)来做到这一点(比如当我们销毁一个对象实例后,我们将对象指针的指置为nil)。但是假如我们抛开以上所说的这两点不谈,单单来研究在Delphi中,究竟有没有办法来判断一个对象指针是否可用,那情况会如何呢?

在Object Pascal中,一个类可以有两种类型的方法,一种称为对象方法(Object Method),另一种是类方法(Class Method)。所谓对象方法,指的是方法的定义是针对对象(或称实例)的,因此调用该方法需要基于某个对象(或称实例),比如类的析构函数Destroy就是一个对象方法(其实我们经常用到的绝大部分方法都是对象方法)。而类方法,指的是方法的定义是基于一类对象而言,因此调用该方法不需要基于特定的对象实例,比如类的构造函数Create就是如此。这一点,对我们有些启发。判断一个对象指针是否可用,似乎可以通过以下步骤来完成。首先,我们可以判断该对象指针是否是nil,如果是,那么大功告成,确定不可用无疑;如果否,那么尝试执行该对象的某个对象方法,看看是否出现诸如无效内存访问等的异常,由此来判断该对象是否可用。用如下代码来验证我们的想法:

var

Obj: TObject;

begin

  Obj := TObject.Create;  //1.创建一个对象

  Obj.Free;             //2.释放刚刚创建的对象,此时内存被回收

  If Obj = nil then        //3.判断指针是否为空,(这一步往往不成功,因为对象

//被释放,Delphi也不会自动将对象指针置空)

    ShowMessage(‘对象指针不可用。’)

  else

  begin

       Try

If Obj.ClassType = TObject then  //4.调用TObject的一个对象方法

ShowMessage(‘对象类型为TObject’);

        Except

          ShowMessage(‘对象指针不可用。’)

        End;

  end;

end;

执行上述代码,我们发现,即使Obj.Free已经执行,Obj.ClassType依然可用。这表明,并不是所有的对象方法一定要依赖于某个对象实例才能够访问。究其原因,是因为这个对象方法不需要访问某个对象实例所申请的内存。从这个意义上来说,TObject.ClassType方法并不象是一个是真正的对象方法,而颇有些类方法的味道。

执行上述代码,我们还可以发现,一个对象执行Free方法,只是将其在创建时所申请的内存释放全部释放,但是并不影响到对象指针本身的值。对象指针还是指向原来的内存地址。同时,由于某些对象方法(如ClassType)实现的特殊性,即使对象已经被释放了,对象方法的调用结果仍然正确。

综上所述,我们可以得出一个结论,那就是,一个对象指针是否能够被判断为是否可用,要看该对象指针所属的类,是否提供了访问对象实例内存的途径——这个途径可以是方法,也可以是属性。那么,现在具体到各个类中,情况又如何呢?

TObject,该类是所有类的祖先类,没有办法作出判断。

TPersistent,由TObject派生而来,创建对象实例时不需要申请额外的内存,所以也没有办法判断。

TComponent,由TPersistent派生而来,增加了许多在创建对象实例时需要申请额外内存的属性,所以从理论上来说,它是可判断的。代码如下:

function ComponentExists(AComponent: TComponent): Boolean;

begin

  try

    AComponent.HasParent; //注意:这个句子也可以为”AComponent.Tag;”

                         //或者为”AComponent.Name”

    result := True;

  except

    result := False;

  end;

end;

通过调用ComponentExists,我们可以得知一个TComponent类型的对象指针是否可用,而不管该对象指针是否已经被释放,是否被置为nil。

其他类,如TControl,TWinControl,或者TButton等等,只要是由TComponent派生而来,则TComponent的判断方法依然适用。

还有其他一些用户自定义的类,若是直接由不能判断的类(比如TObject和TPersistent)派生而来,但是没有需要在实例化时申请内存的属性,那么也没有办法判断;反之,则可以。据个例子来说:

假设我们有一个TPerson类,定义如下:

TPerson = Class(TObject)

Private

  FSex: TSex; // TSex 是枚举类型的性别;

  FFirstName: String;

  FLastName: String;

  //…

Public

  property Sex: TSex read FSex write FSex;

  property FirstName: String read FFirstName write FFirstName;

  property LastName: String read FLastName write FLastName;

  //…

end;

那么,对于TPerson类型的指针Person,可以用如下代码判断指针是否可用:

       Try

Person.Sex;

//或者 Person.FirstName;

//或者 Person.LastName;

result := True; //指针可用

Except

  result := False;//指针不可用

end;

   

以上我们探讨的只是一种技术上的可能性。想要强调的一点是,即使有一个好的可行的办法,也不鼓励经常这么做。因为,一个逻辑严密的程序,本来就应能够杜绝去访问一个无效的指针。

   更多文章

[文终]

 


[Web开发]如何判断微信内置浏览器  [办公软件]如何判断某个工作薄名称已存在或已打开
[搜索优化]如何判断一个IP是搜索引擎的机器人  
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    An error occurred on the server when processing the URL. Please contact the system administrator.

    If you are the system administrator please click here to find out more about this error.

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao 信息产业部ICP备案号:鄂ICP备11006601号

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台