【问题标题】:Delphi: How to free object created dynamically as a parameter of methodDelphi:如何释放动态创建的对象作为方法的参数
【发布时间】:2017-01-01 15:46:29
【问题描述】:

我有一个以参数为对象的方法(下面的代码片段):

TMyObject=class(TObject)
  constructor Create();
  destructor Destroy();override;
end;

implementation

function doSomething(x:TMyObject):integer;
begin
  //code
end;

procedure test();
var
  w:integer;
begin
  w:=doSomething(TMyObject.Create);
  //here: how to free the created object in line above?
end;

如何销毁在被调用方法doSomething内创建的对象?

【问题讨论】:

  • 别偷懒。创建一个变量!
  • @DalijaPrasnikar stackoverflow.com/a/4510268今天的力量与我同在!
  • @DalijaPrasnikar,仅当接口参数为const 时才会出现泄漏。我说的对吗?
  • @kobik:你也可以使用const,但是如果你将它传递为doSomething(TMyObject.Create);,它会泄漏。如果您将其传递为doSomething(TMyObject.Create as IMyInterface);,它将不会泄漏。我总是使用后一种形式。

标签: delphi object free


【解决方案1】:

为了释放对象实例,你需要有一个可以调用Free()的引用。

由于您正在就地创建对象实例作为参数,因此您将拥有的唯一引用是 doSomething() 参数内部的引用。

您要么必须在 doSomething() 内使用 Free 它(这是我不建议这样做的做法):

function doSomething(x: TMyObject): Integer;
begin
  try
    //code
  finally
    x.Free;
  end;
end;

或者,您需要在test() 中创建一个附加变量,将其传递给doSomething(),然后FreedoSomething() 返回后将其传递:

procedure test();
var
  w: Integer;
  o: TMyObject
begin
  o := TMyObject.Create;
  try
    w := doSomething(o);
  finally
    o.Free;
  end;
end;

虽然有人可能认为使用引用计数对象可以就地创建对象并让引用计数释放对象,但由于以下编译器问题,这种构造可能不起作用:

The compiler should keep a hidden reference when passing freshly created object instances directly as const interface parameters

前 Embarcadero 编译器工程师 Barry Kelly 在 StackOverflow 的回答中证实了这一点:

Should the compiler hint/warn when passing object instances directly as const interface parameters?

【讨论】:

  • 如果接口参数不是const或者使用as ISomeInterface传递的,它会起作用。见我的其他 cmets。您对接口被破坏的评论有点恐慌,而且不是真的。
  • @RudyVelthuis 是的,它会这样工作。但它是非常脆弱的代码,因为如果您更改方法签名,您可以在完全不相关的地方破坏代码 - 方法调用。我不会建议它。并且接口被破坏了,因为许多 Delphi 开发人员不断地编写被上述错误破坏的代码。即使是有经验的人。我必须时不时地告诉人们这个错误。
  • 更改签名总是一个坏主意。但是使用as,无论有没有const,它都不会脆弱。
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2011-01-14
  • 2013-09-14
  • 2019-09-09
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多