把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;