状况
我正在从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
。我不太了解Free
和Destroy
的行为。当我必须摆脱一个我不再需要的对象时,我使用Free
。当我覆盖析构函数时,我可以释放对象并进行其他操作吗?
简而言之,什么时候使用免费?什么时候我应该更喜欢Destroy?
答案 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;
正如一个补充说明,我在上面看到的用法缺少一些东西。如果Create
和Free
之间的代码引发了一些异常怎么办?该程序将退出,它永远不会被释放。因此,您应该使用try / finally
块...
a := TFraction.Create(225, 35);
try
ShowMessage(a.getFraction);
finally
a.Free;
end;
这样可以确保无论try
和finally
之间发生什么,finally
和end
之间的代码始终都会被调用。
答案 1 :(得分:3)
如果对象指针不是nil,顺便说一下,我看到我也有可能覆盖
destructor
。我不太了解Free
和Destroy
的行为。
Free()
会调用析构函数。
Destroy()
是实际的析构函数。
当我必须摆脱一个我不再需要的物体时,我使用
Free
。当我覆盖析构函数时,我可以释放对象并进行其他操作吗?
是。当对象处于被破坏的过程中时,将调用析构函数。覆盖析构函数是执行与正在销毁的对象相关的清理操作的好地方。
简而言之,什么时候使用免费?什么时候我应该更喜欢Destroy?
您可以直接拨打Destroy()
,但通常最好拨打Free()
并让其为您拨打Destroy()
。