在Delphi中,我要从已经创建的基类强制转换继承的类。我相信这在两个类之间共享基类地址,但是继承的类的额外成员会获得分配给它们的额外内存,但不会被初始化。
如果然后释放共享基类,这是否会导致继承类的成员发生内存泄漏?
如果是这样,如果我想保持基类不变,什么是清除继承的类成员的最佳方法?
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.
最佳答案
这里没有内存泄漏,但是强制转换仍然是错误的。
您担心以下代码行:
castbaseclass := TInherited(baseclass);
由于Delphi类是引用类型,因此
baseclass
和castbaseclass
都是指针。您在此处所做的所有工作都分配了一个指针变量。您以后再也不会参考castbaseclass
。如果这样做,则可能会出现运行时错误,因为编译器认为castbaseclass
是TInherited
实例,但实际上它是不太专业的类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_;
但是你不能写:
var
base: TBase;
inherited_: TInherited;
....
base := TBase.Create;
inherited_ := base;
关于delphi - Delphi Cast:内存泄漏?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31298362/