有两个类t1,t2,T2继承T1,创建两个实例a,b.我调用b.free后,还可以访问b.showmsg,但a.free后,就不能访问a.showmsg,为什么b会没有释放掉啊?以下是程序:type
 T1 = class
   private
      i:integer;
      j:integer;
      s1:String;
   public
      procedure ShowMsg();
      constructor Create();
      destructor  Destroy();override;
   end;  T2 = class(T1)
     private
          s2:String;
          n:integer;
     public
         procedure ShowMsg1();
         constructor Create();
         destructor  Destroy();override;
    end;var
  Form1: TForm1;
   a:T1;
   b:T2;
implementation
{$R *.dfm}
{ T2 }
constructor T2.Create;
begin
   inherited;
  n := 101;
  s2 := 'this is t2';
  Showmessage('t2 create');
end;destructor T2.Destroy;
begin
   n := 0;
   s2 := '';
   showmessage('t2 destory');
  inherited;
end;procedure T2.ShowMsg1;
begin
   ShowMessage(IntToStr(n)+s2);
end;{ T1 }
constructor T1.Create;
begin
   i := 5;
   j:= 10;
   s1 := 'this is t1 ';
   ShowMessage('t1 create');
end;destructor T1.Destroy;
begin
  i := 0;
  j := 0;
  s1 := '';
  ShowMessage('t1 destory');
  inherited;
end;procedure T1.ShowMsg;
begin
  ShowMessage(IntToStr(i)+IntToStr(j)+s1);
end;procedure TForm1.Button1Click(Sender: TObject);
begin
  a := t1.Create;end;procedure TForm1.Button2Click(Sender: TObject);
begin
  b := t2.Create;
end;procedure TForm1.Button3Click(Sender: TObject);
begin
  a.Free;
end;procedure TForm1.Button4Click(Sender: TObject);
begin
  b.Free;
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
  b.ShowMsg1;
  b.ShowMsg;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
  a.ShowMsg;
end;end.

解决方案 »

  1.   

    b.showmsg的结果是一些我没有赋值的数字。
      

  2.   

    因为b从a继承,而showmsg在a中定义且定义为一般的静态函数,所以showmsg在内存中属于全局函数。在编译中,b.showmsg并静态的编译到showmsg所在的内存指针,所以并不因为b的消亡而消亡。相反,如果a消亡了,那么showmsg的内存就会被清空,所以...
      

  3.   

    我只创建b,没有创建a。我先创建b,然后释放b,再调用b.showmsg,这和a应该没有关系吧。a都没有创建啊。
      

  4.   

    T2 = class(T1)
    我只创建b,没有创建a。我先创建b,然后释放b,再调用b.showmsg,这和a应该没有关系吧。a都没有创建啊.T1为T2的父类,在创建子类的时候首先调用父类的CREATE,然后才调用本身的CREATE,这就是继承机制,所以不管你是否创建a,在创建b的时候自动调用了a的CREATE,b可以看为是T1的实例。
      

  5.   

    没有virtual或dynamic标识的是静态方法。程序启运时就被装配的内存的静态全局区。
    不需要创建类的实例就可以调用了。如:
    -------------------------------------------
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      Ta = class
        procedure ShowMsg();
      end;
      Tb = class(Ta)
        procedure ShowMsg();
      end;
      TForm1 = class(TForm)
        Button3: TButton;
        Button4: TButton;
        procedure Button3Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
      private
        { Private declarations }
        a: ta;
        b:tb;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}{ Tb }procedure Tb.ShowMsg(AMsg: string);
    begin
      showmessage('tb');
    end;{ Ta }procedure Ta.ShowMsg(AMsg: string);
    begin
      showmessage('ta');
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
      b.ShowMsg;
    end;procedure TForm1.Button4Click(Sender: TObject);
    begin
      a.ShowMsg;
    end;end.
    -------------------------------------
    这里的a和b并没有被创建,但是调用成功。因为程序一启动时a.ShowMsg和b.ShowMsg就已在内存中存在
      

  6.   

    补充一下:
    调用对象的静态方法,其实是调用该对象的类的静态方法。该方法在进程的内存中有且只有一个装配。不像virtual或dynamic有多个装配。
      

  7.   

    不用想这么多
    你只要知道Free后所得结果为未定义(所以可能成功,可能不成功),不要用就行了