class(TInterfacedObject) 是否需要 Delphi 中的析构函数?
Does class(TInterfacedObject) need a destructor in Delphi?
我 运行 在这种情况下 Destroy()
永远不会被调用。
unit Unit2;
interface
type
// Interface
ITest = Interface(IInterface)
function IsTrue() : Boolean;
end;
TmyClass = class(TInterfacedObject, ITest)
public
// Interface implementation
function IsTrue() : Boolean;
constructor Create();
destructor Destroy(); override;
end;
implementation
constructor TmyClass.Create();
begin
inherited Create();
end;
destructor TmyClass.Destroy();
begin
inherited Destroy();
end;
published
// Property
property IsItTrue: Boolean read IsTrue;
end.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
fMyClass: TmyClass;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
fMyClass.Free; // if refcount = 0 this works, if refcount <> 0 pointer error.
//or
fMyClass := Nil; // no error but Destroy wil not be executed
Close();
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fMyClass := TMyClass.Create();
end;
end.
阅读this article,只有构造函数没有实现析构函数。
这有什么特别的原因吗?
我是否应该通过实施 finalization
部分释放(如果需要)将在 myClass
中定义的所有其他对象?
析构函数未被调用的最可能原因是您没有将对象分配给接口变量。
procedure Test1;
var
vMyObj : TObject;
begin
vMyObj := myclass.Create;
end; <-Destructor NOT called here
procedure Test2;
var
vMyIntf : IInterface;
begin
vMyIntf := myclass.Create;
end; <-Destructor IS called here.
如果是这样,我邀请您阅读this answer了解更多信息。
你的fMyClass
变量是对象引用,不是接口,所以它不参与TInterfaceObject
的引用计数。
你需要改变这个:
fMyClass: TmyClass;
对此:
fMyClass: ITest;
然后你就可以完全摆脱 fMyClass.Free;
:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
fMyClass: ITest;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
fMyClass := nil; // no error and Destroy will be executed
Close();
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fMyClass := TMyClass.Create();
end;
end.
fMyClass := nil;
仅当 fMyClass
是接口变量而不是对象引用时才会调用引用计数,并且您不能在接口变量上调用 Free()
。
我 运行 在这种情况下 Destroy()
永远不会被调用。
unit Unit2;
interface
type
// Interface
ITest = Interface(IInterface)
function IsTrue() : Boolean;
end;
TmyClass = class(TInterfacedObject, ITest)
public
// Interface implementation
function IsTrue() : Boolean;
constructor Create();
destructor Destroy(); override;
end;
implementation
constructor TmyClass.Create();
begin
inherited Create();
end;
destructor TmyClass.Destroy();
begin
inherited Destroy();
end;
published
// Property
property IsItTrue: Boolean read IsTrue;
end.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
fMyClass: TmyClass;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
fMyClass.Free; // if refcount = 0 this works, if refcount <> 0 pointer error.
//or
fMyClass := Nil; // no error but Destroy wil not be executed
Close();
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fMyClass := TMyClass.Create();
end;
end.
阅读this article,只有构造函数没有实现析构函数。
这有什么特别的原因吗?
我是否应该通过实施 finalization
部分释放(如果需要)将在 myClass
中定义的所有其他对象?
析构函数未被调用的最可能原因是您没有将对象分配给接口变量。
procedure Test1;
var
vMyObj : TObject;
begin
vMyObj := myclass.Create;
end; <-Destructor NOT called here
procedure Test2;
var
vMyIntf : IInterface;
begin
vMyIntf := myclass.Create;
end; <-Destructor IS called here.
如果是这样,我邀请您阅读this answer了解更多信息。
你的fMyClass
变量是对象引用,不是接口,所以它不参与TInterfaceObject
的引用计数。
你需要改变这个:
fMyClass: TmyClass;
对此:
fMyClass: ITest;
然后你就可以完全摆脱 fMyClass.Free;
:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
fMyClass: ITest;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
fMyClass := nil; // no error and Destroy will be executed
Close();
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fMyClass := TMyClass.Create();
end;
end.
fMyClass := nil;
仅当 fMyClass
是接口变量而不是对象引用时才会调用引用计数,并且您不能在接口变量上调用 Free()
。