存在下面的一个类
//******定义部分********* type TTest = class(TObject) protected tNum:Integer; tStr:string; public constructor Create(Num:Integer;Str:string); destructor Destroy; procedure Free; property Num:Integer read tNum; property Str:string read tStr; function GetRnd:string; end; //*******实现部分********** { TTest } constructor TTest.Create(Num: Integer; Str: string); begin inherited Create; //初始化信息 tNum:=Num; tStr:=Str; end; destructor TTest.Destroy; begin tNum:=-2046; tStr:='对象被释放啦!'; inherited Destroy; end; procedure TTest.Free; begin if Self <> nil then Self.Destroy; Self:=nil; inherited Free; end; function TTest.GetRnd: string; begin Result:=IntToStr(Random(10000)); end;
很简单的一个类、那么有下面的测试
procedure TForm1.FormCreate(Sender: TObject); var k:TTest; begin k:=TTest.Create(2046,'Hello!');//实例化、 ShowMessage(k.Str);//显示Hello k.Free;//释放对象 ShowMessage(k.Str); //显示空字符串(也许是零长度字符串、我没关注)、 //返回空、说明对象确实被释放、 ShowMessage(k.GetRnd);//重点:这里依旧可以返回一个值 end;
首先这里在栈里创建了一个指向TTest类实例的指针k、但是这个实例是放在堆里的、
前三句应该没什么特别的、
从第一句开始、再次尝试显示k.Str返回空字符串、这也比较能想得通、因为已经把k指向空指针、自然会返回空(我觉得更应该是内存访问报错猜对)、最神奇的是最后一句、为何k.GetRnd这个函数还能返回值呢?对象已经被释放、并且k已经变成空指针、那么这个函数他又是如何找到的呢?另外这个函数到底是放在堆还是放在栈里?