开发者

Should object free objects which it contains? [closed]

开发者 https://www.devze.com 2023-03-30 21:59 出处:网络
Closed. This question is opinion-based. It is not currently accepting answers. Want to improve this question? Update the question so it can be answered with facts and citations by editing th
Closed. This question is opinion-based. It is not currently accepting answers.

Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.

Closed 7 years ago.

Improve this question

Recently I have a dillema.

Consider such example:

unit Unit2;

interface

uses
  Classes;

type
  TMyObject = class(TObject)
  private
    FDataStream: TMemoryStream;
    procedure SetD开发者_运维知识库ataStream(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.

As you see, the TMyObject can have an instance of TMemoryStream. Now, I am wondering what TMyobject should do when it is freed? Should it also free FDataStram or should it left as it is?

Is there any guidline for such scenerio?

Thanks.


In the example you give it seems to me that your TMyObject receives an instance from somewhere else. If it isn't in the TMyObject constructor's to take over ownership of the stream it receives, it should certainly not free it when it is destroyed.

To preserve your sanity, stick to this rule: the class/code that instantiates an object should destroy it.

And as your constructor does not create the data stream instance, the destructor should not free it.


TMyObject didn't create the TMemoryStream itself. The stream was given as a reference to TMyObject via the constructor, so TMyObject should not free it. Freeing the memorystream is the responsibility of whoever created it.


Whether you are supposed to free it or not depends on semantics. If you are the sole user of the stream and the (previous) owner supposes you own it, then you should free it when you are finished.

This is indicated by user code that does something like:

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

When you are the owner, the user only has to create the stream (memory, file, etc.) and hand to to you.

If you, however, were only given the memorystream owned by other code in order to read a part and then the owner of the stream passes it to another class/routine, then it is not yours and you should keep it alive.

This all depends on clear documentation indicating who will free what. It is not as clear as the previous posters make it look like. You (and the users of your class) can only decide what is best.

You could of course add another Boolean property / parameter indicating if your class owns the object or not. But only do that if it is unclear if the class is supposed to do that.


The object that owns the object should free it. Typically the object that creates it is the owner. That's the case in 99% or more of situations. Sometimes ownership is transferred to another object and when that happens it is the responsibility of the new owner to free the object.

Although I would point out that in your example, it doesn't matter what you put in Destroy since it will never be called - you forgot to mark it with the override directive.

0

精彩评论

暂无评论...
验证码 换一张
取 消