Duplicating a class instance
I’ve run into a strange problem, and I wonder if there is a solution out there.
I have working code that do this
aCopy := TMyClass(Self.ClassType.Create);
The .Create will also eventually call .AfterConstruction – which poses a problem – as I do things in it which basically shouldn’t be done with the copy.
So – I add another constructor to the base class to set a flag to indicate it is a copy – but – how do I invoke the other constructor?
A cast like the one below, is not a viable solution, it seems – as I end up with a nil pointer AV.
aCopy := TMyClass(Self.ClassType).AnotherCreate;
How do I invoke the right constructor in a clean and efficient way?
TMyClassType = class of TMyClass;
TMyClassType(Self.ClassType).AnotherCreate ?
aCopy := TMyClass(Self.newInstance());
aCopy.AnotherCreate;
Alexander Sviridenkov – Yup, that was the way. And when you posted that, I realized it is not the first time I’ve done that mistake.
I blame age 😉
Paul TOTH – I’ve never used that one.
Googled it, and it seems it is not advisable. http://stackoverflow.com/questions/10460925/instanceclass-newinstance-vs-instanceclass-create
It is used in Application.CreateForm, TReader and CreateParentedControl, so it’s probably not so evil 😉
but my favorite solution will be a method like this
aCopy := AnotherInstance();
function TMyClass.AnotherInstance: TMyClass;
begin
Result := TMyClass(NewInstance);
Result.FAnother := True;
Result.Create;
end;
or
function TMyClass.AnotherInstance: TMyClass;
begin
Result := TMyClass.AnotherCreate();
end;
If AfterConstruction does something that should not be done in all cases where you create a new instance, then you are doing something wrong. Solve that problem and all the other problems cease to exist.
Stefan Glienke – I agree. It’s a kludge, but it was necessary to avoid duplicate objects used for dirty checking, being added to the instance dictionary – and that is revealing only a tiny part of the monsters hiding in our class hierarchy.