Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I create an object of the same type as itself?

Tags:

delphi

I have a class of mine, lets call it TMyObject, which should return a slightly modified copy of itself. So, one of its functions should return an object of the same type as itself:

function TMyObject.TrimEnds: TMyObject;
begin
  Result:= TMyObject.Create;
  Result.DoStuff;
edn;

Can I do that? Is it legit what am I doing?

I mean, I already tried it and the compiler allows me to do it, but I wonder if there will be long time/hidden negative effects.

Any thoughts will be appreciated. Thanks.


Edit: The new slightly modified copy will be saved to disk. It is some kind of 'Save as...'. How it works: The original object creates a copy of itself, instructs this copy to do some changes and to save to disk. Then the original frees the copy. This way I keep the original object in memory unchanged but I have a modified version of this to disk.

You may think that my object holds a picture. What I need is a function that returns a slightly modified copy of the picture.

like image 761
Server Overflow Avatar asked Nov 21 '09 16:11

Server Overflow


3 Answers

but I wonder if there will be long time/hidden negative effects.

I don't see any, and I used to do this with my own linked lists, and never had any problem. I think it is pretty much the same as creating an instance in any other place.

like image 139
eKek0 Avatar answered Nov 01 '22 04:11

eKek0


I guess you are right, this piece of code seems wrong to me. You always have to make it clear who's responsible for freeing the object you return. In most cases, this object will not be freed.

A better approach is to usually let the caller create the object, pass it to your method (you only need a procedure then) which modifies it.

I am curious to know why you would want to return a "slightly modified version" of your object. It sounds counter-intuitive to me...

like image 33
kuzkot Avatar answered Nov 01 '22 04:11

kuzkot


As others had said, there's nothing wrong with that but there may be better ways.

Variant 1: Change this into class method and give it a meaningful name.

class function TMyObject.CreateSpecialized: TMyObject;
begin
  Result := TMyObject.Create;
  //initialize Result
end;

anObj := TMyObject.CreateSpecialized;

Variant 2: Use a constructor. You can have multiple constructors in a class.

constructor TMyObject.CreateSpecialized;
begin 
  Create; // make sure everything is initialized correctly
  // now do custom initialization
end;

anObj := TMyObject.CreateSpecialized;

Usage is same in both examples but in second case your intentions are clearer to a random reader.

If you want to take one object and create another one based on first object's fields, use a constructor with parameter.

constructor TMyObject.CreateSpecialized(obj: TMyObject);
begin
  Create;
  intField := obj.IntField * 2;
end;

anObj := TMyObject.CreateSpecialized(otherObj);
like image 38
gabr Avatar answered Nov 01 '22 02:11

gabr