In Delphi, I'm casting an inherited class from a base class which is already created. I believe this shares the base class addresses between the two classes, but the inherited's class's extra members get extra memory allocated to them, but are not initialised.
If the shared base class is then freed, does this cause a memory leak for the Inherited's class's members?
If so, what is the best way to clean up the inherited classes members if I want to leave the base class untouched?
program Project1;
uses
SysUtils;
type
TBase = class(TObject)
public
basemember : string ;
Constructor Create() ;
end;
TInherited = class(TBase)
public
inheritedmember : string ;
Constructor Create() ;
end ;
Constructor TBase.Create() ;
begin
basemember := 'Basemember' ;
Writeln ('basemember') ;
end ;
Constructor TInherited.Create() ;
begin
inheritedmember := 'inheritedmember' ;
Writeln ('inheritedmember') ;
end ;
var
baseclass : TBase;
castbaseclass : TInherited;
begin
Writeln ('Base Class');
baseclass := TBase.Create();
Writeln ('');
Writeln ('Cast Inherited Class');
castbaseclass := TInherited(baseclass);
baseclass.Free; //memory leak?
ReadLn;
end.
There is no memory leak here, but the cast is still wrong.
You are concerned about this line of code:
castbaseclass := TInherited(baseclass);
Since Delphi classes are reference types, baseclass
and castbaseclass
are both pointers. All you have done here is assigned a pointer variable. You never subsequently refer to castbaseclass
. If you did do that, then there would be potential for runtime errors because the compiler believes that castbaseclass
is a TInherited
instance, but in fact it is an instance of a less specialized class, TBase
.
However, you have a very deep misunderstanding.
I'm casting an inherited class from a base class which is already created. I believe this shares the base class addresses between the two classes, but the inherited's class's extra members get extra memory allocated to them, but are not initialised.
No! Absolutely not. In order to instantiate a TInherited
instance you must call a constructor of TInherited
. You cannot create an instance of one class and expect it to ever morph into another class. The type of an instance is determined once and for all when it is created. The memory for an instance is allocated when the instance is created, and at no other time.
So, if you want a TInherited
, create one. If you want a TBase
, create one. But you cannot create a TBase
and change its type to be a TInherited
. What you can do is create a TInherited
and then assign it to a variable of type TBase
. That's because TInherited
is derived from TBase
.
So you can write:
var
base: TBase;
inherited_: TInherited; // _ because inherited is a keyword
....
inherited_ := TInherited.Create;
base := inherited_;
But you cannot write:
var
base: TBase;
inherited_: TInherited;
....
base := TBase.Create;
inherited_ := base;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.