如何将以下"class reference"机制从德尔福转换为C++11?
How would I translate the following "class reference" mechanism from Delphi to C++11?
我已经使用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.
输出:Base says hi to Mark
Base says hi to Mark
ChildA says hi to Mark
ChildB says hi to Mark
注意,当传递对子类的引用时,将创建该子类。在本演示中,故意不调用childdb中的基构造函数,以使"类引用"的概念更加明显。
最接近的方法是使用模板函数
template<typename ClassType>
Base* ConstructSomething(string name)
{
return new ClassType(name);
}
int main()
{
ConstructSomething<Base>("Mark");
ConstructSomething<ChildA>("Mark");
}
但ClassType
不能在运行时选择-必须在编译时知道
c++没有像Delphi那样的内置类引用。类引用不仅仅是虚构造函数;您还可以定义(虚拟和非虚拟)类方法,这非常方便。
您可以通过使用c++模板来模仿类引用,但是它带有一些样板代码,并且您必须为类和元类定义单独的类。更不用说这是一种相当单一的c++方式。
// some central header
template <typename Base>
class Metaclass;
// your header
class Base
{
public:
Base (const String& name) { /*...*/ }
};
template<>
class Metaclass<Base>
{
public:
virtual Base* create (const String& name);
};
extern Metaclass<Base> classof_Base;
class ChildA : public Base
{
public:
ChildA (const String& name) { /*...*/ }
};
template<>
class Metaclass<ChildA> : public Metaclass<Base>
{
public:
// note how I'm making use of C++'s support for covariance
ChildA* create (const String& name) override;
};
extern Metaclass<ChildA> classof_ChildA;
class ChildB : public MyBase
{
public:
ChildB (const String& name) { /*...*/ }
};
template<>
class Metaclass<ChildB> : public Metaclass<Base>
{
public:
ChildB* create (const String& name) override;
};
extern Metaclass<ChildB> classof_ChildB;
// your source file
Metaclass<Base> classof_Base;
Base* Metaclass<Base>::create (const String& name)
{
return new Base (name);
}
Metaclass<ChildA> classof_ChildA;
MyBase* Metaclass<ChildA>::create (const String& name)
{
return new ChildA (name);
}
Metaclass<ChildB> classof_ChildB;
MyBase* Metaclass<ChildB>::create (const String& name)
{
return new ChildB (name);
}
现在您可以在c++中复制Delphi代码:
Base* constructSomething (Metaclass<Base>& classType, const String& name)
{
return classType.create (name);
}
int main (void)
{
constructSomething (classof_Base, "Mark");
std::sprintf ("n");
constructSomething (classof_ChildA, "Mark");
std::sprintf ("n");
constructSomething (classof_ChildB, "Mark");
std::sprintf ("n");
}
相关文章:
- C++结构到德尔福记录dll调用
- 如何在德尔福中C++制作与此类似的结构
- 德尔福在回调中出现 GUI 问题
- 我有点坚持德尔福的动态虚拟通道
- 加密和解密C++和德尔福中的一些字符串
- SDK指针的问题 - c++到德尔福的翻译
- 德尔福仿制药:E2037:'XXX'声明与以前的声明不同
- 德尔福动态DLL调用中的奇怪行为
- C++德尔福的int8_t[20]类型
- 如何在德尔福中C++参数数组指针算术
- 将德尔福记录与"polymorphic"转换为C / C ++
- 从C++ .dll到德尔福表单应用程序的PostMessage问题
- C++德尔福头文件翻译:带有指向 void 的指针的函数
- 明确表示对德尔福的所有权
- 德尔福中C++“const”返回类型相当于什么
- 将C++ FOR循环转换为德尔福
- 无法从德尔福文件安装嵌入C++生成器上的铬
- 从C++到德尔福的转换
- 德尔福复制记忆 vs C++ memcpy
- 如何将以下"class reference"机制从德尔福转换为C++11?