首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Delphi中,类(TInterfacedObject)需要析构函数吗?

在Delphi中,类(TInterfacedObject)需要析构函数吗?
EN

Stack Overflow用户
提问于 2019-12-02 22:14:24
回答 2查看 705关注 0票数 1

我在这种从未调用过Destroy()的情况下运行。

代码语言:javascript
复制
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.

代码语言:javascript
复制
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中定义的所有其他对象?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-03 06:09:09

您的fMyClass变量是一个对象引用,而不是一个接口,因此它不参与TInterfaceObject的引用计数。

您需要更改以下内容:

fMyClass: TmyClass;

要这样做:

fMyClass: ITest;

然后你就可以完全摆脱fMyClass.Free;了:

代码语言:javascript
复制
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是接口变量而不是对象引用时,fMyClass := nil;才会调用引用计数,并且您不能在接口变量上调用Free()

票数 1
EN

Stack Overflow用户

发布于 2019-12-02 23:15:56

析构函数不被调用的最可能的原因是你没有将你的对象赋值给一个接口变量。

代码语言:javascript
复制
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以获取更多信息。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59140720

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档