在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类是引用类型,因此baseclasscastbaseclass都是指针。您在此处所做的所有工作都分配了一个指针变量。您以后再也不会参考castbaseclass。如果这样做,则可能会出现运行时错误,因为编译器认为castbaseclassTInherited实例,但实际上它是不太专业的类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/

10-12 06:22