線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:747
推到 Plurk!
推到 Facebook!

多态问题

答題得分者是:Chance36
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-07-08 21:36:54 IP:222.183.xxx.xxx 未訂閱
各位大大好: 我已经释放了对象之后,为什么点两次释放按钮,程序仍然会执行free命令?
procedure TForm1.freebtnClick(Sender: TObject);
begin
//这里已经进行判断了,为什么点击第二次释放按钮的时候,仍然会执行base.free动作?
  if base <> nil then 
    base.Free;
end;
源代码如下:
unit Unit1;    interface    uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;    type
  TBase = class(TObject)
  public
    procedure Showmsg; virtual;
    destructor Destroy; override;
  end;
  TDerived = class(TBase)
  public
    procedure Showmsg; override;
    destructor Destroy; override;
  end;
type
  TForm1 = class(TForm)
    freebtn: TButton;
    procedure freebtnClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    base: Tbase;
  end;    var
  Form1: TForm1;    implementation    {$R *.dfm}    { TBase }
destructor TBase.Destroy;
begin
  inherited;
  showmessage('Tbase free');
end;    procedure TBase.Showmsg;
begin
  showmessage('hello world! by Tbase');
end;    { TDerived }    destructor TDerived.Destroy;
begin
  inherited;
  showmessage('Tderived free');
end;    procedure TDerived.Showmsg;
begin
 // inherited;
  showmessage('hello world! by TDerived!');
end;    procedure TForm1.freebtnClick(Sender: TObject);
begin
  if base <> nil then
    base.Free;
end;    procedure TForm1.FormCreate(Sender: TObject);
begin
  base := TDerived.Create;
  base.Showmsg
end;    end.     
感谢您的指点
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-07-08 22:07:09 IP:211.20.xxx.xxx 未訂閱
引言:
procedure TForm1.freebtnClick(Sender: TObject);
begin
//这里已经进行判断了,为什么点击第二次释放按钮的时候,仍然会执行base.free动作?
  if base <> nil then 
    base.Free;
end;
zzmbeyond01 你好
改成如下寫法就OK了,某些物件Free後會自動設為nil,某些又不會,至於那些會那些不會,我沒去研究。
procedure TForm1.freebtnClick(Sender: TObject);
begin
//这里已经进行判断了,为什么点击第二次释放按钮的时候,仍然会执行base.free动作?
  if Assigned(base) then 
    FreeAndNil(base);
end;
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-07-08 22:34:42 IP:222.183.xxx.xxx 未訂閱
再问一下,是不是用基类声明的对象指向派生类生成的对象时, 如:Base:=TDerived.create; 调用Freeandnil(base)或base.free方法,是不是也就把所引用的派生类对象释放干净
zzmbeyond01
中階會員


發表:98
回覆:167
積分:53
註冊:2003-09-07

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-07-08 22:54:31 IP:222.183.xxx.xxx 未訂閱
FreeAndNil  free 的区别找到了    http://delphi.ktop.com.tw/topic.php?topic_id=45708  
引言: aaa.free 後雖然aaa object所佔的記憶體被釋放但 aaa仍指到那塊被釋放的記憶體 所以比較保險的寫法為free之後 aaa := nil; 在使用aaa方法前再加 if Assigned(aaa) then aaa.XXX .... FreeAndNil 同等於 Free之後再assign nil 給該變數
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;    
不过我感觉是先赋nil,再作的free动作?? 發表人 - zzmbeyond01 於 2004/07/08 22:57:36
系統時間:2024-06-10 13:56:46
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!