Delphi管理可用内存

时间:2016-08-17 23:36:05

标签: delphi

状况

我正在从Marco Cantu的书中学习Delphi,我已经有了OOP的经验,因为我经常使用Java和PHP。为了更好地理解我正在阅读的内容,我做了这个测试:

type
 TFraction = class
  private
   number: double;
   num, den: integer;
   fraction: string;
   function hcf(x: integer; y: integer): integer;
  public
   constructor Create(numerator: integer; denominator: integer); overload;
   constructor Create(value: string); overload;
   function getFraction: string;
 end;

这是一个超级简单的类,可将十进制数转换为分数。我不包括我定义构造函数和函数的代码的其他部分,因为它们对我的问题没用。我正在以这种方式创建对象。

var a: TFraction;
begin

 a := TFraction.Create(225, 35);
 ShowMessage(a.getFraction);
 //The output of ^ is 45/7
 a.Free;

end;

问题

据我所知,我知道在使用它之后我必须摆脱它,事实上我正在使用Free。通过这种方式,我释放了内存,避免了内存泄漏。

顺便说一下,我看到我也有可能覆盖destructor。我不太了解FreeDestroy的行为。当我必须摆脱一个我不再需要的对象时,我使用Free。当我覆盖析构函数时,我可以释放对象并进行其他操作吗?

简而言之,什么时候使用免费?什么时候我应该更喜欢Destroy?

2 个答案:

答案 0 :(得分:7)

通常,如果您需要在对象销毁期间执行某些操作,则使用析构函数,否则将无法自动完成。就像释放你在构造函数中初始化的内存一样。在您的示例中,不需要覆盖析构函数,因为(可能)您不会创建任何需要手动销毁的内容。

另外,请记住,Destroy根本不打算由您调用 - 无论是内部还是外部。 Free会自动为您调用 - 只需要做一些额外的工作。 Free检查对象是否为nil,如果不是Destroy则仅调用nil

以此为例:

type
  TMyObject = class(TObject)
  private
    FSomeOtherObject: TSomeOtherObject;
  public
    constructor Create;
    destructor Destroy; override;
  end;

constructor TMyObject.Create;
begin
  inherited;
  FSomeOtherObject:= TSomeOtherObject.Create;
end;

destructor TMyObject.Destroy;
begin
  FSomeOtherObject.Free;
  inherited;
end;

正如一个补充说明,我在上面看到的用法缺少一些东西。如果CreateFree之间的代码引发了一些异常怎么办?该程序将退出,它永远不会被释放。因此,您应该使用try / finally块...

a := TFraction.Create(225, 35);
try 
  ShowMessage(a.getFraction);
finally
  a.Free;
end;

这样可以确保无论tryfinally之间发生什么,finallyend之间的代码始终都会被调用。

答案 1 :(得分:3)

  

顺便说一下,我看到我也有可能覆盖destructor。我不太了解FreeDestroy的行为。

如果对象指针不是nil,

Free()会调用析构函数。

Destroy()是实际的析构函数。

  

当我必须摆脱一个我不再需要的物体时,我使用Free。当我覆盖析构函数时,我可以释放对象并进行其他操作吗?

是。当对象处于被破坏的过程中时,将调用析构函数。覆盖析构函数是执行与正在销毁的对象相关的清理操作的好地方。

  

简而言之,什么时候使用免费?什么时候我应该更喜欢Destroy?

可以直接拨打Destroy(),但通常最好拨打Free()并让其为您拨打Destroy()