gpt4 book ai didi

delphi - 将对象引用作为接口(interface)传递

转载 作者:行者123 更新时间:2023-12-03 18:16:29 25 4
gpt4 key购买 nike

我将创建的对象传递给另一个对象的构造函数,该对象需要一个该对象实现的接口(interface)。

  ISomeInterface = interface
['{840D46BA-B9FB-4273-BF56-AD0BE40AA3F9}']
end;

TSomeObject = class(TInterfacedObject, ISomeinterface)
end;

TSomeObject2 = class
private
FSomeInterface: ISomeinterface;
public
constructor Create(SomeObject: ISomeInterface);
end;

var
Form1: TForm1; // main form
SomeObject: TSomeObject;

constructor TSomeObject2.Create(SomeObject: ISomeInterface);
begin
FSomeInterface := SomeObject;
end;

// main form creating
procedure TForm1.FormCreate(Sender: TObject);
var SomeObject2: TSomeObject2;
begin
SomeObject := TSomeObject.Create;
// SomeObject2 := TSomeObject2.Create(nil); // ok
SomeObject2 := TSomeObject2.Create(SomeObject); // not ok
try
// do some things
finally
SomeObject2.Free;
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
SomeObject.Free; // if passed to a SomeObject2 Constructor - freeing it causing av
end;

在我关闭主窗体后,它给了我一个 AV 和内存泄漏——整个主窗体都泄漏了。如果我将 nil 传递给 TSomeObject 构造函数,一切都很好。编译器是否通过引用计数释放 FSomeInterface 而我不应该尝试释放 mainForm destructor 中的 SomeObject?我该如何避免?

最佳答案

TSomeObject 继承自 TInterfacedObject,因此被引用计数。您的 TSomeObject 实例未进行引用计数,应将其删除或替换为接口(interface)变量。

如果您需要在 FormCreate 中创建的 TSomeObject 的实例,您应该将它分配给一个 ISomeInterface 类型的变量,这样引用计数也将为此工作。

另一种方法是继承自 TInterfacedPersistant 而不是 TInterfacedObject 以避免引用计数。

解释代码中发生的事情:

procedure TForm1.FormCreate(Sender: TObject);
var SomeObject2: TSomeObject2;
begin
{ Here you create the instance and assign it to a variable holding the instance.
After this line the reference count of the instance is 0 }
SomeObject := TSomeObject.Create;
// SomeObject2 := TSomeObject2.Create(nil); // ok
{ Using the instance as a parameter will increase the reference count to 1 }
SomeObject2 := TSomeObject2.Create(SomeObject); // not ok
try
// do some things
finally
{ Freeing SomeObject2 also destroys the interface reference FSomeInterface is
pointing to (which is SomeObject), decreasing the reference count to 0, which
in turn frees the instance of TSomeObject. }
SomeObject2.Free;
end;
{ Now, after SomeObject is freed, the variable points to invalid memory causing the
AV in FormDestroy. }
end;

关于delphi - 将对象引用作为接口(interface)传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16273137/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com