I have multiple descendent classes sharing an ancestor. When I want to destroy an object I don't know what the actual type is, because the pointer holding the actual object has an ancestor type.
Thinks of it like you have multiple descendent from TButton
, saving all objects in an array of type TButton, now when you want to destroy the objects, calling TButton(ButtonArray[I]).Destroy
cause memory leaks, because it didn't call Destroy method of descendent types.
I want an approach to properly destroy descendent classes from the ancestor Destroy method.
CodePudding user response:
This problem doesn't exist.
Since the destructor Destroy
is a virtual method, the correct one will be chosen automatically at run-time, because Delphi knows the actual class of every object instance, no matter what kind of pointers you have to it in your source code. (Indeed, try ShowMessage(MyObj.ClassName)
.)
For example, given TFruit
, TApple = class(TFruit)
, and TBanana = class(TFruit)
and
var
a, b: TFruit;
begin
a := TApple.Create;
b := TBanana.Create;
a.Destroy; // calls TApple.Destroy, if properly overridden
b.Destroy; // calls TBanana.Destroy, if properly overridden
end;
(except that, of course, you never write x.Destroy
but x.Free
).
So why doesn't this work for you? Well, this is a common mistake:
TChild = class(TParent)
constructor Create;
destructor Destroy;
end;
must be
TChild = class(TParent)
constructor Create;
destructor Destroy; override; // <-- Add override!
end;
Otherwise you will not override TParent.Destroy
, but simply introduce a new destructor with the same name.
Actually, the compiler tries to warn you about this:
[dcc32 Warning] W1010 Method 'Destroy' hides virtual method of base type 'TObject'
or something like that.