假设有如下类声明:
try
  TMyObj = class
  public
    procedure SayHello;
  end;
SayHello实现如下:
procedure TMyObj.SayHello;
begin
   
end;
下面的代码会不会引发错误,请说明原因:
var
  MyObj: TMyObj;
begin
  MyObj := TMyObj.Create;
  MyObj.Free;
  MyObj.SayHello;
end;

解决方案 »

  1.   

    Delphi中默认的方法为静态方法,非虚方法!
    静态方法在编译期已经能计算出内存地址,直接call 地址就OK了。
      

  2.   

    free后对象都被释放了,还可以调用该对象的方法?
      

  3.   

    type
      TMyObj = class
      public
        procedure SayHello;
      end;procedure TMyObj.SayHello;
    begin
        showmessage('ok');
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      MyObj: TMyObj;
    begin
      MyObj.SayHello;
    end;测试环境D7+xp3是不会报错,很难理解
      

  4.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
      TMyObj = class
      public
        aa :string;
        procedure SayHello; 
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var 
      MyObj: TMyObj;
    begin 
      MyObj := TMyObj.Create; 
      MyObj.Free;
      myobj.aa := '11111111';
      MyObj.SayHello; end;{ TMyObj }procedure TMyObj.SayHello;
    begin
      showmessage(aa);
    end;end.
    把代码 改成这样就会能看出来了。free 比没有对对象的实例 进行赋值为空的freeandnil(MyObj);
      

  5.   

    有啥不好理解的~
    MyObj.SayHello编译后被翻译成TMyObj.SayHello,和实例是否被创建是没有任何关系的。
    SayHello又不是Virtual方法,又不占用实例空间,不创建实例访问很正常。
    OO的本质实现是让每个类实例独享数据域,而共享其方法区。
    方法区分静态方法(Delphi默认)与虚方法。
    静态方法通过call 进程相对地址的形式来调用。
    虚方法是放在一个VMT表中,访问虚方法需要查表!
      

  6.   

    肯定会报错的,因为free了!!
      

  7.   

    free后,类的reflect(指针)还在栈内。
      

  8.   

    liangpei2008说的在理,曾今我也遇见过这个情况,不过楼主的例子有一定的特殊性,没有使用任何此类或者实例的成员是不会报错的。类的静态方法的调用是编译器已经将方法地址编译成一个公共区域,所有成员访问这个方法将直接跳到这个方法的入口地址,只要运行后这个地址就存在了,当这个方法中没有使用必须由这个成员提供的资源时代码不会报错。
      

  9.   

    var 
      MyObj: TMyObj; 
    begin 
      MyObj := TMyObj.Create; 
      MyObj.Free; 
      MyObj.SayHello; 
    end; 
    我发现真接调用类中的方法也不会出错,如果你要使用静态方法那就不要创建实例
    如果创建、后又放掉那内存就是空的了,当然会错
    var 
      MyObj: TMyObj; 
    begin 
      MyObj.SayHello; 
    end; 
      

  10.   

    var 
      MyObj: TMyObj; 
    begin 
      MyObj.SayHello; 
    end; 
     
    只要SayHello中没有引用类的成员,就不会报错
    实例只要定义,不需创建,其实就类似于类方法(class method)