在Delphi中,我正在从已经创建的基类中继承一个继承的类。我相信它共享两个类之间的基类地址,但是继承的类的额外成员获得了分配给它们的额外内存,但是没有初始化。
如果随后释放了共享基类,是否会导致Inherited的类成员出现内存泄漏?
如果是这样,如果我想保持基类保持不变,那么清理继承类成员的最佳方法是什么?
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.
答案 0 :(得分:7)
这里没有内存泄漏,但演员阵容仍然是错误的。
您担心这行代码:
castbaseclass := TInherited(baseclass);
由于Delphi类是引用类型,baseclass
和castbaseclass
都是指针。你在这里所做的一切都被分配了一个指针变量。你永远不会引用castbaseclass
。如果你这样做了,那么就有可能出现运行时错误,因为编译器认为castbaseclass
是TInherited
实例,但实际上它是一个不太专业的类的实例,{{1} }。
然而,你有一个非常深刻的误解。
我正在从已经创建的基类中继承一个继承的类。我相信它共享两个类之间的基类地址,但是继承的类的额外成员获得了分配给它们的额外内存,但是没有初始化。
没有!绝对不。为了实例化TBase
实例,您必须调用TInherited
的构造函数。你不能创建一个类的实例,并期望它变成另一个类。实例的类型在创建时一劳永逸地确定。实例的内存在创建实例时分配,而不是在其他时间分配。
因此,如果您想要TInherited
,请创建一个。如果您想要TInherited
,请创建一个。但是,您无法创建TBase
并将其类型更改为TBase
。您可以做的是创建TInherited
,然后将其分配给TInherited
类型的变量。这是因为TBase
来自TInherited
。
所以你可以写:
TBase
但你不能写:
var
base: TBase;
inherited_: TInherited; // _ because inherited is a keyword
....
inherited_ := TInherited.Create;
base := inherited_;