tabc = class
    procedure test;
    procedure show;
  end;procedure tabc.show;
begin
  ShowMessage('ok');
end;procedure tabc.test;
begin
  FreeAndNil(Self);
end;
var
  o: tabc;
begin
  o := tabc.Create;
  o.test;   //内部释放
  o.show;   //仍然可以弹出提示窗
end;
也没有发现内存泄漏
在实际编程中,因为类要处理一些数据,在类处理完毕后会触发回调函数,在函数中我会把类的Self传递过去,并释放
不知道这样做是否安全,是不是一个不良的习惯?

解决方案 »

  1.   

    把'ok'换成一个成员变量试试!test之后show就会出错!!!而且FreeAndNil(Self)之后,o依然不为nil,你试试!
      

  2.   

    这样做,肯定是不对的, 显然你释放后再次调用o.show这个方法里没有再次访问实例里成员, 所以这里即使你不创建 tabc 一样可以这样做 o: Tabc; o.show; 但是一旦你的show里访问了私有类实例成员 那么必然会发生内存违规(也要看运气)
      

  3.   

    即使o:tabc ; o:=nil, o.show也不会出错, 问题在于show在这里根本不访问私有的成员变量, 所以o 本身实例是什么都无所谓 , 一旦你的show里有了访问私有变量的代码, 就肯定有问题了
      

  4.   

    谢谢两位的解答,其实我是想了解下在类的内部释放自己是否合理?
    因为某些时候,我需要一个类去处理一些事情,处理完后通知我(也就是界面)
    我现在做法是在回调函数中把这个self释放掉,我总觉得这不是个很好的办法
    因为在回调函数中释放了自己的话,如果类内部还有其他操作就会出内存错误了吧
      

  5.   

    一般的原则是由创建者释放。当然也有例外,比如创建成接口,比如单实例,比如由objectlist来管理等等。
      

  6.   

    类中释放自己,要分情况,当一个实例确定不再使用时,可以引一个方法来释放自己

    Txxx = Class(Txxx)
    public
      procedure Free2;
    end;procedure Txxx.Free2;
    begin
      DoSomething;
      Free;
    end;在Free2中,调用 Free;就象前面两位所说,Free后不能在引用任何非Class定义的类的数据成员,这里需要注意一下,在类的事件中引用Free就要留意,有些事件调用返回后,还会访问类的数据成员,因此要出错,
    比如想在 Form.OnActivate中,Free掉Self就要出错当你调用
    实例.方法的时候,就是把实例的地址传到方法中当Self使用比如:
    var
      o: tabc;
    begin
      o := nil;
      o.test;   
    你在Tabc.test中判断Self肯定=NIL再举个例:
    procedure TABC.AAA(i : integer);
    //该过程实际上就是普通过程的这种格式: procedure (Self : TABC; i : integer);
    begin
    end;当实行
    ABC.AAA(1)
    实际上是执行 AAA(ABC , 1);