在Delphi中从func/proc获取对象

Jur*_*nka 9 delphi creation object

从delphi中的函数/过程返回简单对象的最佳实践是什么?

例如.2种代码:

将创建的对象作为引用传递,在Proc中填充对象,然后将其销毁

procedure Proc(var Obj: TMyObject);
begin
  // populate Obj
end;

O := TMyObject.Create;
try
  Proc(O);
  // manipulate populated object
finally
  O.Free;
end;
Run Code Online (Sandbox Code Playgroud)

或者 从函数中获取创建的对象,在操作后销毁

function Func: TMyObj;
begin
  Result := TMyObj.Create;
end;

O := Func;
if O <> nil then
begin
  try
    // manipulate
  finally
    O.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

Rob*_*edy 8

没有最好的做法.但是,您应该做的主要事情是确保始终清楚谁在任何给定时间负责销毁对象,即使发生异常也是如此.

创建新实例并返回它的函数没有任何问题.这样的功能是工厂.您可以像处理类的构造函数一样对待它,因此您应该确保它的行为类似于构造函数:返回有效对象或抛出异常.它永远不会返回null引用.

function Func: TMyObj;
begin
  Result := TMyObj.Create;
  try
    Result.X := Y;
  except
    Result.Free;
    raise;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

这是一种你经常看不到的异常处理模式,但这对于这种功能很重要.返回对象将所有权从函数转移到调用者,但前提是它设法完全执行.如果由于异常而必须提前离开,它会释放对象,因为调用者无法自行释放它.(由于异常而终止的函数没有返回值.)调用者将使用它如下:

O := Func;
try
  writeln(O.X);
finally
  O.Free;
end;
Run Code Online (Sandbox Code Playgroud)

如果有一个异常,Func那么O永远不会被分配,所以没有任何东西可供调用者释放.


当调用者创建对象并将其传递给另一个函数以初始化它时,不要将参数设为"var"参数.这对调用者施加了某些限制,调用者必须使用与函数请求的类型完全相同的变量,即使创建了某些后代类型.

这样的功能应该不会释放对象.调用者不会对它调用的函数赋予所有权责任,特别是当它计划在函数返回后使用该对象时.