gpt4 book ai didi

delphi - 工厂模式、内存泄漏

转载 作者:行者123 更新时间:2023-12-03 14:47:33 24 4
gpt4 key购买 nike

我正在阅读 Hodges 的书“More Coding in Delphi”,其中有关工厂模式的部分。努力学习东西。将我的代码分解成小单元。我使用 ReportMemoryLeaksOnShutDown := True; 并且以下代码会产生内存泄漏。为什么会发生这种情况以及如何解决它?

unit Unit2;

interface

uses
Generics.Collections, System.SysUtils;

type
TGatewayTpe = (gtSwedbank, gtDNB);

type
TBaseGateway = class

end;

type
TSwedbankGateway = class(TBaseGateway)
end;

type
TGatewayFunction = reference to function: TBaseGateway;

type
TGatewayTypeAndFunction = record
GatewayType: TGatewayTpe;
GatewayFunction: TGatewayFunction;
end;

type
TGatewayFactory = class
strict private
class var FGatewayTypeAndFunctionList: TList<TGatewayTypeAndFunction>;
public
class constructor Create;
class destructor Destroy;
class procedure AddGateway(const AGatewayType: TGatewayTpe;
const AGatewayFunction: TGatewayFunction);
end;

implementation

class procedure TGatewayFactory.AddGateway(const AGatewayType: TGatewayTpe;
const AGatewayFunction: TGatewayFunction);

var
_GatewayTypeAndFunction: TGatewayTypeAndFunction;
begin
_GatewayTypeAndFunction.GatewayType := AGatewayType;
_GatewayTypeAndFunction.GatewayFunction := AGatewayFunction;

FGatewayTypeAndFunctionList.Add(_GatewayTypeAndFunction);
end;

class constructor TGatewayFactory.Create;
begin
FGatewayTypeAndFunctionList := TList<TGatewayTypeAndFunction>.Create;
end;

class destructor TGatewayFactory.Destroy;
begin
FreeAndNil(FGatewayTypeAndFunctionList);
end;

initialization
TGatewayFactory.AddGateway(
gtSwedbank,
function: TBaseGateway
begin
Result := TSwedbankGateway.Create;
end
);

end.

最佳答案

这是一个编译器缺陷。在单元的初始化部分定义匿名方法似乎会导致该匿名方法未最终确定,从而导致泄漏。在这种情况下,我将通过将代码从初始化部分移动到类构造函数来解决该问题。

因此,完全删除initialization部分,并将类构造函数更改为如下所示:

class constructor TGatewayFactory.Create;
begin
FGatewayTypeAndFunctionList := TList<TGatewayTypeAndFunction>.Create;
AddGateway(
gtSwedbank,
function: TBaseGateway
begin
Result := TSwedbankGateway.Create;
end
);
end;

这是我可以制作的最简单的复制品:

unit Unit1;

interface

implementation

type
TProc = reference to procedure;

var
Foo: TProc;

initialization
ReportMemoryLeaksOnShutdown := True;
Foo := procedure begin end;

end.

当您将此单元包含在项目中时,匿名方法会被报告为已泄漏。

但是这个变体不会报告泄漏:

unit Unit1;

interface

implementation

type
TProc = reference to procedure;

var
Foo: TProc;

procedure DoInit;
begin
Foo := procedure begin end;
end;

initialization
ReportMemoryLeaksOnShutdown := True;
DoInit;

end.

该缺陷已在 XE8 中修复。

关于delphi - 工厂模式、内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34694081/

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