Memory management 对象创建未指定给变量

Memory management 对象创建未指定给变量,memory-management,delphi-10.3-rio,Memory Management,Delphi 10.3 Rio,我希望使用类的方法,而不将其创建赋值给变量。例如: type TMyObject = class public procedure DoSomething; end; implementation procedure MyObjDoesSomething; begin TMyObject.Create.DoSomething; end; { TMyObject } procedure TMyObject.DoSomething; begin // ... en

我希望使用类的方法,而不将其创建赋值给变量。例如:

type
  TMyObject = class
  public
    procedure DoSomething;
  end;

implementation

procedure MyObjDoesSomething;
begin
  TMyObject.Create.DoSomething;
end;

{ TMyObject }

procedure TMyObject.DoSomething;
begin
  // ...
end;
如您所见,在
myobjectdoesmething
中,我没有将
TMyObject.Create
分配给
TMyObject
变量


这是否会对内存使用产生某种影响,甚至是我没有想到的其他事情?

如果您
创建一个对象来为其分配内存,则必须在使用该对象释放内存时调用该对象上的
Free()
,否则内存会泄漏,如果您多次创建这些对象,会随着时间的推移影响内存

如果您不想使用显式变量引用对象(为什么?),可以使用带块的
,例如:

程序myobjdoesmething;
开始
使用TMyObject.Create do
尝试
剂量测定法;
最后
自由的
结束;
结束;
另一个选项是使类实现一个
接口
,然后您可以让编译器的接口引用计数为您释放对象。这比上面的开销多一点,但您不必担心手动处理内存,例如:

类型
IMyObject=接口
[{896FF4FA-A974-4A8B-9EA5-414C138635E4}]
程序剂量测定;
结束;
TMyObject=class(TInterfacedObject、IMyObject)
公众的
程序剂量测定;
结束;
实施
手术方法;
开始
(TMyObject.Create as IMyObject).DoSomething;
结束;
{TMyObject}
程序TMyObject.DoSomething;
开始
// ...
结束;
但实际上,只需使用变量即可。使用它不需要任何费用:

程序myobjdoesmething;
变量
Obj;
开始
Obj:=TMyObject.Create;
尝试
目标剂量测定法;
最后
对象自由;
结束;
结束;

是的,有一个很大的影响:很好的内存泄漏

调用对象的构造函数,但从不释放创建的对象。每次调用MyObjDoesMething时,都会泄漏一个对象实例

为了解决这个问题,您可以创建一个DoSomething类方法,如下所示:

type
  TMyObject = class
  public
    class procedure DoSomething;
  end;
procedure MyObjDoesSomething;
begin
  TMyObject.DoSomething;
end;
然后可以调用DoSomething,而无需创建如下对象:

type
  TMyObject = class
  public
    class procedure DoSomething;
  end;
procedure MyObjDoesSomething;
begin
  TMyObject.DoSomething;
end;

作为类方法,DoSomething实现不能使用对象实例变量(字段)。

通常不建议使用构造。事实上,这是一个有争议的话题。@fpiette是的,但在像这样的简单案例中,它可能引起的争议性问题是相当没有意义的。这不是with的真正用法,是吗。这些问题在一个说教的例子中是没有意义的,这一点没有抓住重点。真正重要的是真实世界的棕地维护问题。在我的真实环境中,
TMyObject.DoSomething
使用RTTI将他的一个方法分配给另一个对象的事件属性。如果我在
DoSomething
之后调用
Free
,那么当另一个对象的事件触发时,我会遇到访问冲突,因此我想知道在我的示例中调用
DoSomething
是否是一种解决方法。。。实现接口并没有解决问题,所以我决定存储
TMyObject
(而不是一个局部变量),并在另一个对象被破坏时释放它。@MarinaFinetti“如果我在
DoSomething
之后调用
free
,那么当另一个对象的事件触发时,我会得到访问冲突”-有意义,如果您是
Free
ing拥有用于事件处理程序的方法的对象,并且该方法尝试通过其
Self
指针访问该对象的成员。“实现接口并没有解决问题”-如果将接口对象用于事件处理程序,则必须采取额外措施,确保在将对象分配给事件时,对象的refcount不会降至0。“基本上,同样的问题——过早地破坏目标我很好奇为什么你不想使用局部变量?”DavidHeffernan在Remy Lebeau的回答下回答道。似乎很清楚的是,问题中的代码对这个问题的影响更大。看起来您有一个问题,但这里的代码并没有表达出来。你应该照雷米说的去做,并提供一份能证明实际问题的报告。