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

Ric*_*ick 6 delphi class record delphi-xe2

我有一个类,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.'   ),
...
Run Code Online (Sandbox Code Playgroud)

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

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

value.loadFromOffset( offset );
Edit1.Text := value.getShortString;
Run Code Online (Sandbox Code Playgroud)

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

value := TiffTypes[ fldType ].data;

value.loadFromFile( f, offset, count );
InternalRepresentation := TTiffAscii( value.storage );
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 7

由于您的类具有公共基类TiffData,因此您可以class of TiffData在记录中使用,例如:

type
  TtiffType = record
    name  : string;
    bytes : word;
    data  : class of TiffData; // <-- here
    desc  : string;
  end;
Run Code Online (Sandbox Code Playgroud)

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

  • 不可以.让我们说`Data`指向`TTiffByte`.如果`TiffData.Create`不是虚拟的,调用`Data.Create`**将不会**调用`TTiffByte.Create`.在使用元类创建对象时,虚拟构造函数非常重要. (3认同)
  • 构造函数不需要*是虚拟的.无论如何都会创建正确的对象.如果后代需要覆盖它,您只需要它是虚拟的,这与使任何其他方法虚拟的标准相同.在这方面,构造者并不特别. (3认同)

Gra*_*ter 3

你需要的是一个元类。

type
  TTiffDataClass = class of TiffData;
Run Code Online (Sandbox Code Playgroud)

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

TTiffType = record
  name  : string;
  bytes : word;
  data  : TTiffDataClass;
  desc  : string;
end;
Run Code Online (Sandbox Code Playgroud)

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

TTiffByte= class(TiffData)
end;
Run Code Online (Sandbox Code Playgroud)

这应该有效:

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

正如雷米在回答中所说,要小心构造函数。