如何从一个常量的记录数组中引用一个类?

时间:2014-05-04 23:36:24

标签: class delphi delphi-xe2 record

我有一个类,TiffData包含用于加载和显示数据的抽象方法,还有一些祖先类,如TTiffByte,TTiffAscii,TTiffShort,用于定义这些方法。

我还有一个常量数组或记录,可让我根据IFD中记录的数据类型查找有关类型的信息。

我无法弄清楚,如何为每个数组元素存储关联的类。

type
    TtiffType = record
      name  : string;
      bytes : word;
      data  : class;   {  ?  }
      desc  : string;
    end;

const
TiffTypes : array[ 1 .. 18 ] of TTiffType =  (

{01} ( name: 'byte';  bytes : 1; data: TTiffByte;     { ? }
       desc: '8-bit unsigned number.'   ),
{02} ( name: 'ascii';  bytes : 1; data: TTiffAscii;   { ? }
       desc: '8 bit byte that contains a 7 bit ASCII code; the last byte must be NULL (binary zero)'   ),
{03} ( name: 'short';  bytes : 2; data: TTiffShort;   { ? }
       desc: '16-bit (2-byte) unsigned integer.'   ),
...

我想要做的是在数组中保存对类的引用:

value := TiffTypes[ fldType ].Data.Create;

value.loadFromOffset( offset );
Edit1.Text := value.getShortString;

或在数组中保存一个构造函数:

value := TiffTypes[ fldType ].data;

value.loadFromFile( f, offset, count );
InternalRepresentation := TTiffAscii( value.storage );

3 个答案:

答案 0 :(得分:7)

由于您的班级有一个共同的基类TiffData,您可以在记录中使用class of TiffData,例如:

type
  TtiffType = record
    name  : string;
    bytes : word;
    data  : class of TiffData; // <-- here
    desc  : string;
  end;

然后使用Data.Create将按预期工作,只要TiffData的构造函数声明为virtual并且每个派生类都会覆盖它。

答案 1 :(得分:3)

您需要的是元类。

type
  TTiffDataClass = class of TiffData;

然后您可以像这样使用它:

TTiffType = record
  name  : string;
  bytes : word;
  data  : TTiffDataClass;
  desc  : string;
end;

如果您有TiffData的后代,那么您可以使用它。例如:

TTiffByte= class(TiffData)
end;

这应该有效:

{01} ( name: 'byte';  bytes : 1; data: TTiffByte;     { ? }
       desc: '8-bit unsigned number.'   ),

正如雷米在答案中所说,要小心施工人员。

答案 2 :(得分:0)

感谢Remi和Graymatter!我使用了两个答案中的信息来获得以下结果。几乎任何不同的东西都会发出警告,错误或运行时异常。

定义许多类来管理各种数据类型,TTiffData的所有祖先。

Type

TTiffData = class(TObject)
    constructor create; virtual;
    procedure LoadFromIFD( var aValue; Count : LongWord  ); virtual; abstract;
end;

TTiffShort = class(TTiffData)
    constructor create; override;
    procedure LoadFromIFD( var aValue; Count : LongWord  ); override;
end;

TTiffAscii = class(TTiffData)
    constructor create; override;
    procedure LoadFromIFD( var aValue; Count : LongWord  ); override;
end;

...

注意:我使用&#39;覆盖&#39;而不是虚拟的&#39;在孩子们预防&#34;方法&#39; *&#39;隐藏基本类型的虚拟方法&#39; TTiffData&#39;&#34;警告。

数组如下所示:

type
    TTiffDataClass = class of TTiffData;

    TtiffType = record
      name  : string;
      bytes : word;
      data  : TTiffDataClass;
      desc  : string;
    end;

const


   TiffTypes : array[ 1 .. 18 ] of TTiffType =  (
{01} ( name: 'byte';  bytes : 1; data: TTiffShort;
       desc: '8-bit unsigned number.'   ),
{02} ( name: 'ascii';  bytes : 1; data: TTiffAscii;
       desc: '8 bit byte that contains a 7 bit ASCII code; the last byte must be NULL (binary zero)'   ),

...
); 

用法:

    {  Load }
    Value := TiffTypes[ fldType ].data.Create;

    if Indirect then begin
        Value.LoadFromFile( f, Offset, Count );
        end

    else begin
        ValueLoadFromIFD( Offset, Count );
        end;


    { Display }
    aStringGrid.Cells[ 8, i ] := Value.ShortDisplay;