这是控制对象场类型生命周期的最佳方法吗?

Edu*_*aia 5 delphi oop

TMyClass = class(TObject)
private
  FMyObject: TObject;
  function GetMyObject: TObject;
public
  property MyObject: TObject read GetMyObject write FMyObject;
end;

function TMyClass.GetMyObject: TObject;
begin
  if FMyObject = nil then
    FMyObject := TObject.Create;

  Result := FMyObject;
end;
Run Code Online (Sandbox Code Playgroud)

有时,"MyObject"不是在内部创建的,而是在外部创建并分配给参数.如果在外部创建此对象,则无法在此上下文中释放它.

我应该创建一个TList并添加内部创建的所有对象并销毁析构函数上的所有内容吗?

如果参数是在内部创建的,那么如何控制参数的生命周期?你建议做什么?有没有任何模式可以做到这一点?

Jam*_*ass 7

我在Property Setter中设置了一面旗帜

procedure TMyClass.SetMyObject(AObject: TObject);
begin
  if Assigned(MyObject) and FIsMyObject then
    FMyObject.Free;
  FIsMyObject := False;
  FMyObject := AObject;
end;

function TMyClass.GetMyObject: TObject;
begin
  if FMyObject = nil then
  begin
    FMyObject := TObject.Create;
    FIsMyObject := True;
  end;

  Result := FMyObject;
end;

Destructor TMyClass.Destroy;
begin
    if FIsMyObject then
        FMyObject.Free;
end;
Run Code Online (Sandbox Code Playgroud)


ain*_*ain 3

我想最好的办法是重新设计你的代码,这样这个问题就不会出现——这种所有权模糊性是一团糟。

无论如何,一种选择是使用(引用计数)接口。这在循环引用的情况下是有问题的。

如果外部创建的对象一定不是唯一的引用,那么您仍然可以创建该对象的内部副本,例如

procedure TMyClass.SetMyObject(const Value: TObject);
begin
   MyObject.Assign(Value);
end;
Run Code Online (Sandbox Code Playgroud)

您可以将外部对象分配给与内部对象不同的字段,然后您不在Free析构函数中将该字段分配给该字段。或者在属性设置器中设置一个标志,以便您知道不要释放外部对象...