gpt4 book ai didi

Delphi 接口(interface)和类变量类型

转载 作者:行者123 更新时间:2023-12-03 15:49:35 25 4
gpt4 key购买 nike

我读到接口(interface)是解耦代码的好东西,Nick Hodges 写了一篇关于它的很好的章节。读到我已经生成了这段代码:

//interfaces
type
ILocalization = interface
['{1D144BCE-7D79-4672-8FB5-235422F712EE}']
function localize(const aWordId: string): string;
end;

type
IActions = interface
['{31E8B24F-0B17-41BC-A9E4-F93A8E7F6ECF}']
procedure addWord(const aIndex, aWord: string);
procedure removeWord(const aIndex: string);
end;

//implementation
type
TLocalization = class sealed (TInterfacedObject, ILocalization, IActions)
private
FTranslationList: TDictionary<string, string>;
public
constructor Create;
destructor Destroy; override;
//interface implementations
function localize(const aWordId: string): string;
procedure addWord(const aIndex, aWord: string);
procedure removeWord(const aIndex: string);
end;

我计划使用此类来本地化(翻译)我的 delphi android 应用程序。

<小时/>

当我要创建该类的实例时,我会执行以下操作。

var
Italiano: TLocalization;
begin
Italiano := TLocalization.Create;
end;

由于 TLocalization 应该继承 AddRef 和 Release 我最终不会尝试这个,但是即使 Italiano 是类类型而不是接口(interface)类型,也会发生这种情况吗?

我的意思是这样的:

  • 意大利语:TLocalization -> 在这里我可以使用所有方法
  • Italiano: ILocalization -> 这里我只能使用 localize 函数

鉴于(正如我已经说过的)TLocalization 继承了 AddRef 和 Release,如果我理解正确的话,我不必释放它。应该和ILocalization一样,但是它还有其他好处吗?我不明白上面2种情况有什么区别

最佳答案

var
Italiano: TLocalization;
begin
Italiano := TLocalization.Create;
// do stuff
end;

这会让您陷入混合不同生命周期模型的陷阱。从代码来看,AddRef 尚未被调用,因此引用计数为 0。因此,您将泄漏该对象。

所以你可以将代码更改为:

var
Italiano: TLocalization;
begin
Italiano := TLocalization.Create;
try
// do stuff
finally
Italiano.Free;
end;
end;

现在你不会泄漏了。

太棒了。但如果您确实引用了会发生什么?

var
Italiano: TLocalization;
Localization: ILocalization;
begin
Italiano := TLocalization.Create;
try
Localization := Italiano as ILocalization;
// do stuff
finally
Italiano.Free;
end;
end;

现在,当您分配给 Localization 时,会调用 AddRef。因此,引用计数将变为 1。当 Localization 超出范围时,将调用 Release,引用计数将返回到 0,并且实例将被销毁。不幸的是,你也明确地破坏了它。对象需要被销毁一次。

要遵循的最干净、最简单的规则是不要混合生命周期模型。如果您通过引用计数进行生命周期管理,则仅这样做。确保在创建对象时始终引用该对象,并让编译器生成引用计数代码来管理生命周期。

确保遵循该规则的一种方法是确保仅通过接口(interface)引用访问对象。像这样:

var
Italiano: ILocalization;
begin
Italiano := TLocalization.Create;
// do stuff
end;

关于Delphi 接口(interface)和类变量类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44258127/

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