Mar*_*wan 1 c++ delphi factory class-reference
我已经使用了一段时间的C++,偶尔会让我感到困惑的一件事是我还没有弄清楚如何在C++中使用这个Delphi Factory构造.
我无法弄清楚的关键部分是如何在C++中传递对类类型的引用.在Delphi中,我们有"TClass"类型.这种类型的变量是对某些类的引用.我们可以使用class of MyClass语法来限制类引用可以引用的类来定义新的类引用类型.
注意术语"Delphi类引用"=/="类的C++实例"
对于那些不熟悉Pascal的人来说,变量是声明的variable: type而不是C风格type variable.同样,函数的返回类型出现在参数列表和名称之后.
我已经在下面的例子中浓缩了语法,以减少它的样板,所以对Delphi开发人员道歉,因为它的格式很糟糕.关键部分在评论中描述.
program demo;
{$APPTYPE CONSOLE}
// declarations
type
Base = class
public constructor Create(name: string); virtual;
end;
// Class reference which refers to Base and its descendants
BaseClass = class of Base;
ChildA = class(Base)
public constructor Create(name: string); override;
end;
ChildB = class(Base)
public constructor Create(name: string); override;
end;
// implementation
constructor Base.Create(name: string);
begin
WriteLn('Base says hi to ' + name);
end;
constructor ChildA.Create(name: string);
begin
inherited Create(name);
WriteLn('ChildA says hi to ' + name);
end;
constructor ChildB.Create(name: string);
begin
WriteLn('ChildB says hi to ' + name);
end;
// *** THIS IS THE BIT THAT I'M INTERESTED IN ***
// The function doesn't know at compile time exactly what class it is being
// asked to construct. The compiler knows that it is or inherits from Base.
// I can't find any kind of "class reference" in C++.
function ConstructSomething(ClassType: BaseClass; name: string): Base;
begin
Result := ClassType.Create(name);
end;
// Equivalent to "main()" in C
begin
// Pass references to a class to the ConstructSomething function
ConstructSomething(Base, 'Mark');
WriteLn('');
ConstructSomething(ChildA, 'Mark');
WriteLn('');
ConstructSomething(ChildB, 'Mark');
WriteLn('');
end.
Run Code Online (Sandbox Code Playgroud)
输出:
Base says hi to Mark
Base says hi to Mark
ChildA says hi to Mark
ChildB says hi to Mark
Run Code Online (Sandbox Code Playgroud)
请注意,当传递对子类的引用时,将创建子类.在本演示中,不要在ChildB中调用基本构造函数,以使"类引用"概念更加明显.
您可以获得的最接近的是使用模板功能
template<typename ClassType>
Base* ConstructSomething(string name)
{
return new ClassType(name);
}
int main()
{
ConstructSomething<Base>("Mark");
ConstructSomething<ChildA>("Mark");
}
Run Code Online (Sandbox Code Playgroud)
但ClassType无法在运行时选择 - 必须在编译期间知道.