在 Base Class 构造函数中调用 Class 函数

Call Class function in the Base Class Constructor

我有一个 Base Class 需要像文件名这样的参数。 TMemIniFile Class.

的创建调用需要此参数

在 Base Class 构造函数中调用当前 Class 类型的 Class 函数的正确方法是什么?

TBaseClassClass = Class of TBaseClass;

TBaseClass = class(TMemIniFile)
protected
  class function FileName: string; virtual; abstract;
public
  // Current Solution
  constructor Create(ClassToCreate: TBaseClassClass); reintroduce;
  // wanted Solution
  constructor Create; reintroduce;
end;

TImplementation = Class(TBaseClass)
protected
  class function FileName: string; override;
end;

// Current Solution
constructor TBaseClass.Create(ClassToCreate: TBaseClassClass);
begin
  inherited Create(ClassToCreate.FileName, Encoding.UTF8);
end;
// Wanted Solution
constructor TBaseClass.Create;
begin
  inherited Create(FileName, Encoding.UTF8); // This call to FileName has a Abstract Error because its calling Filename from TBaseClass. But how to solve this elegant?
end;

//Trying to Clarify: Usage:
myWorkingIniFile: TImplementation.Create;  //Filename is defined in Class and the FileName value is used in the Constructor ...  

我能否以某种方式在构造函数中“动态”进行类型转换?我已经看到使用 RTTI 调用函数名称。但我认为应该有另一种方式。 还是我做的根本就错了?

您永远不应创建包含抽象方法的 class 实例。在您的示例中,您应该只创建 TImplementation 的实例,而不是 TBaseClass。如果您希望 class 是动态的:

procedure Foo;
var
  vMyClass : TBaseClassClass;
begin
  vMyClass := TImplementation; //or vMyClass := GetSomeClass();
  FMyField := vMyClass.Create;
end;

在这种情况下,您通常希望 TBaseClass 的构造函数是虚拟的。

如果你打电话给TBaseClass.Create(TImplementation),你是对的,那是根本错误的

哦,是的,感谢您的评论。 (德语谚语:只见树木不见森林;好像我没有看到显而易见的东西)我想到了这样的事情:

TBaseClass = class(TMemIniFile)
protected
  class function FileName: string; virtual; abstract;
end;

TImplementation = Class(TBaseClass)
protected
  class function FileName: string; override;
public
  constructor Create; reintroduce;
end;

constructor TImplementation.Create;
begin
  inherited Create(Filename, Encoding);
end;

另外,我现在将 AfterConstruction 用于所有其他设置和设置。无需使用 class 函数。