它应该包含它包含的自由对象吗?

时间:2011-08-25 12:14:09

标签: delphi class

最近我有一个dillema。

考虑这样的例子:

unit Unit2;

interface

uses
  Classes;

type
  TMyObject = class(TObject)
  private
    FDataStream: TMemoryStream;
    procedure SetDataStream(const Value: TMemoryStream);
  public
    property DataStream: TMemoryStream read FDataStream write SetDataStream;
    constructor Create(ADataStream: TMemoryStream);
    destructor Destroy;
  end;

implementation

{ TMyObject }

constructor TMyObject.Create(ADataStream: TMemoryStream);
begin
  FDataStream := ADataStream;
end;

destructor TMyObject.Destroy;
begin
  //Should MyObject free FDataStream?
end;

procedure TMyObject.SetDataStream(const Value: TMemoryStream);
begin
  FDataStream := Value;
end;

end.

如您所见,TMyObject可以有一个TMemoryStream实例。现在,我想知道TMyobject在被释放时应该做什么?它是否还应该释放FDataStram还是它应该保留原样?

这样的场景是否有任何指导?

感谢。

4 个答案:

答案 0 :(得分:10)

在示例中,您认为TMyObject从其他地方接收实例。如果它不在TMyObject构造函数中来接管它收到的流的所有权,它肯定不会在它被销毁时释放它。

为了保持理智,坚持这条规则:实例化对象的类/代码应该销毁它

由于构造函数不创建数据流实例,因此析构函数不应释放它。

答案 1 :(得分:3)

TMyObject没有创建TMemoryStream本身。该流作为对TMyObject的引用通过构造函数给出,因此TMyObject不应该释放它。释放内存流是创建它的人的责任。

答案 2 :(得分:1)

是否应该释放它取决于语义。如果您是流的唯一用户并且(之前的)所有者假设您拥有它,那么您应该在完成时释放它。

这由用户代码表示,例如:

x := TMyCode.Create(TMemoryStream.Create));

当您是所有者时,用户只需创建流(内存,文件等)并交给您。

但是,如果您只获得其他代码拥有的内存流以便读取某个部分,然后该流的所有者将其传递给另一个类/例程,那么它不是您的,您应该保持它存活。

这一切都取决于明确的文件,表明谁将释放什么。它并不像以前的海报那样清晰。您(以及您班级的用户)只能决定什么是最好的。

您当然可以添加另一个布尔属性/参数,指示您的类是否拥有该对象。但只有在不清楚班级是否应该这样做的情况下才能这样做。

答案 3 :(得分:1)

拥有该对象的对象应该释放它。通常,创建它的对象是所有者。在99%或更多的情况下就是这种情况。有时所有权转移到另一个对象,当发生这种情况时,新所有者有责任释放该对象。

虽然我会指出在你的例子中,你在Destroy中放入什么并不重要,因为它永远不会被调用 - 你忘了用override指令标记它。