【发布时间】:2019-12-02 14:14:23
【问题描述】:
我在从未调用过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 中定义的所有其他对象?
【问题讨论】:
-
文章中的类没有任何需要清理的资源,所以不需要重写析构函数。你应该找出为什么你的析构函数没有被调用。
-
您的问题是无法回答的。没有minimal reproducible example,所以我们不知道为什么你的析构函数没有被调用。是否需要覆盖默认析构函数是另一个问题,这取决于您在类中声明的字段类型以及您如何使用它们。
-
这里似乎有两个单独的问题:1)
TInterfacedObject是否需要重写其析构函数,以及 2) 为什么永远不会调用您的析构函数。但经验法则是肯定的,它在很大程度上与其他对象一样工作,所以如果你在构造函数中创建/初始化任何东西,或者一般需要任何清理,那么你需要在析构函数中销毁它。为什么从不调用析构函数,如果没有看到足够的代码很难说。 -
TInterfacedObject被引用计数。你的类的声明很好(假设你只处理过IInterface变量),但是如果你从来没有将你的类的对象实例分配给接口变量,那么引用计数将不会被正确管理,所以析构函数不会不叫。请举例说明您如何实际使用该课程,有人可以解释为什么它不能正常工作。 -
@Remy 原来的类和 api 有很多代码要在这里发布。所以,我想简化这个问题。虽然我必须说接口实际上是一个 IMFSourceReaderCallback。但是这个接口的实现方式与我的简单示例中的方式相同。我没有摆脱在 Create() 上初始化的引用计数,它保持为 2。
标签: delphi destroy tinterfacedobject