`
isiqi
  • 浏览: 16158467 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Delphi中的Record

阅读更多
Delphi中的RecordDelphi 2009-05-23 14:21:14 阅读889 评论0 字号:大中小 订阅 Delphi中的Record是什么作者:一笑 人气:0 更新:2008-4-12 16:03:50 出自:WWW.YgRen.CN 在Delphi中的Record类型中,与之C语言对应的即是结构体类型(struct),也可能是为了符合C语言或C++程序员的习惯,对于它在Delphi中的应用存在的一些问题进行初步的说明。在Delphi中的记录体类型有两种方式定义 Type RecTest = record (packed) ID :integer; Name :string; Descript:string; end; 之两种类型的主要区别在于在内存中的存放,Packed是紧缩类型的,可以节省内存空间与存放的空间,但是它定义好了对应的长度,所以不太适合存放不定长的数据,如string类型的数据;同时在使用记录体类型时特别要注意的是使用记录体数组的情况,使用不当不仅仅会出现性能方面的问题,同时也会产生意想不到的错误。如 RecList arrary[0..100] of RecTest,如采用这样的定义的方面,会产生的问题有: 1.当用数组下标访问对应的记录体元素时,到后面的数据记录访问时间会越来越长,如RecList[89] ,它需要将RecTest中移动88个记录长度,由于RecTest是不定长的,所以每次移动的长度也可能不相同,所以导致定位数组中记录体时定位时间长 2.当对记录体进行赋值时,如果想默认或遗忘给某个变量赋值,则会产生比较严重的后果,当应用到该变量时,可能会读取到错误的数值 如一定要使用记录体类型的,可以采用一些变通的方法,如采用数组指针,这样可以大幅提升性能,如针对前面的记录体数据情况,可以多定义一个指针变量,如下: PRecList = ^RecTest RecList arrary[0..100] of PRecList 这样定义相对的好处就是每次移动时,只需要移动记录指针的长度数即可,即在现有的windows系统中,只需要移动4位即可。 所以针对上面的问题,在程序开发中尽量少采用记录体类型,直接定义一个相应的类即可,定义一个相应的类处理的好处时,可以与面对对象的开发的方法相一致,只不过是比记录体多了创建与释放而已,但相应的初始化或方法、属性在类中很容易实现,同时对于程序的扩展类也很容易处理,记录体可能会比较麻烦,如在记录体中增加一个字段,那有可能整个程序都需要变化,但在对象中增加一个属性会显得非常方便,同时也容易对于对象中的属性内容进行初始化处理。 另:在对不定长记录进行再分配空间时,如增加一个长度的空间,在系统中的处理是先开避一块内存地址保存当前内容再在此基础上加一个长度的地址长度,即在相应的内存中需要复制两个长度的地址后才能完成增加长度 ------------------------------------------------------------------ 把DELPHI的RECORD转成简单CLASS 近来把一些DELPHI写的代码重构过程中,遇到点小问题.旧代码是比较纯粹的面向过程方式书写,定义了若干种的RECORD类型来表示应用中的实体信息,当然也少不了定义了大堆对这些RECORD类型各自操作的函数. 重构代码计划我考虑分几步,首先为部分RECORD定义相应的类,然后一步步理清各种实体的派生关系,用多态替换掉原有大量难看的条件判断, 首先就有一个问题摆在面前,首先要解决RECORD与类(对象)相互转换问题,这儿有个问题,旧代码里面的RECORD有部分是临时变量,是栈分配,另一部分则是分配在自定义的几个内存堆里,可以一次简单全部释放. 而DELPHI对象呢,一般都是从一个全局堆里分配,要同RECORD转换,这是关键性的矛盾. 既然回避不了,就想法解决,当仔细跟踪DELPHI对象实例化的过程代码后,才发觉解决方法原来如此简单: 一个简单例子: type THello =class public a:Integer; b:char; c:string; procedure Say; procedure FreeInstance;override;//override它之后,FREE时就不会释放内存. end; THelloRec=record p:pointer;//它是一个TClass指针,这儿纯为占四字节用. a:Integer; b:char; c:string; end; ....................... { THello } procedure THello.Say; begin ShowMessage('Hello'); end; procedure THello.FreeInstance; begin // inherited; end; procedure TForm1.Button1Click(Sender: TObject); var hello:THello; buf:THelloRec; begin // fillchar(buf,sizeof(buf),0);//这句多余了,InitInstance会清空这块内存,记住这点很重要. hello:=THello(THello.InitInstance(@buf));//这样,对象与这个RECORD变量 //就共享同一块空间 hello.a:=500; hello.b:='d'; hello.c:='hello....!!'; hello.Say; ShowMessage(buf.c); // hello.Free; 这个对象自己没分配空间,是使用BUF的空间.因此不要FREE. end; ========================================== 另一种写法可以更直接些.. procedure TForm1.Button1Click(Sender: TObject); var hello:THello; buf :THelloRec; begin buf.p:=THello; hello:=THello(@buf);//这样,对象与这个RECORD变量 //就共享同一块空间 hello.a:=500; hello.b:='d'; hello.c:='hello....!!'; hello.Say; end;
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics