C++ Builder 参考手册 ➙ C++ Builder 的反射 (二) - Reflection Factory
上一篇文章 C++ Builder 的反射 (Reflection) (一) 介绍了从 TObject 继承的类的反射方法,这篇文章继续论述从 TObject 继承的类的反射,根据上一篇文章,做一个通用的类模板,这个类模板需要 C++ 11 / clang 编译器。本文的程序和例子已经用 C++ Builder 10.2.3 版本 clang 32位 和 clang 64位编译器测试通过。
- Reflection Factory 类模板
- 测试控件的反射
- 测试自己写的类的反射
1. Reflection Factory 类模板
THsuanluReflectionFactory 类模板的参数:
- TBaseClass 为可以反射的类的公共父类,通过类名字符串反射创建的类通过这个类型的指针返回;
- TConstructorParams 为反射的类的构造函数的参数的类型,这不是单一的参数,而是一组随意个数和类型的参数,也可以没有。由于创建类的时候,必需调用类的构造函数,所以需要提供类的构造函数的每个参数的类型,请参考 C++ 可变参数的模板,构造函数参数相同的类,可以注册到这个 Reflection Factory 里面;
Register 方法为注册需要反射的类,模板参数 TClassType 为要注册的类;
Create 方法为通过类名字符串创建类,参数 sClassName 为类名字符串,参数 Params 为构造函数的可变参数,通过 new TClassType(Params...) 创建注册的类。
#include
2. 测试控件的反射
- 这个例子在程序开始运行时,即在主窗口的构造函数里面,注册了 TLabel、TButton、TMemo、TEdit、TCheckBox、TRadioButton、TComboBox 等几个控件类,可以使用他们的类名字符串来创建控件对象。
- 由于控件类的构造函数都有一个 TComponent* Owner 参数,在定义 ControlsFactory 的时候,模板参数除了公共父类 TControl 之外,还有一个 TComponent* 参数。
THsuanluReflectionFactory ControlsFactory;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ControlsFactory.Register();
ControlsFactory.Register();
ControlsFactory.Register();
ControlsFactory.Register();
ControlsFactory.Register();
ControlsFactory.Register();
ControlsFactory.Register();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonCreateClick(TObject *Sender)
{
try
{
TControl *p = ControlsFactory.Create(EditClassName->Text, this);
p->Parent = this;
p->SetBounds(EditLeft->Text.ToIntDef(0), EditTop->Text.ToIntDef(0), EditWidth->Text.ToIntDef(80), EditHeight->Text.ToIntDef(30));
}
catch(Exception &e)
{
ShowMessage(e.Message);
}
}
编辑框 EditClassName 输入控件的类名,
编辑框 EditLeft, EditTop, EditWidth, EditHeight 分别用于输入控件的位置和大小,
按钮 ButtonCreate 创建控件,ButtonCreateClick 方法就是点击这个按钮执行的代码。
运行结果:
创建一个 TComboBox:
再创建一个 TCheckBox 和一个 TRadioButton
3. 测试自己写的类的反射
由于本文讨论从 TObject 继承的类的反射,这里写几个类:其中 THsuanluBase 从 TObject 继承,作为其他几个类的公共父类,反射的结果是通过这个类型的指针返回通过类名字符串创建的对象。要注意:通过父类指针访问子类的方法要定义为虚函数。
class THsuanluBase : public TObject
{
public:
virtual void PrintMessage(void){ Form1->Memo1->Lines->Add(L"这是父类的 PrintMessage 方法"); }
};
//---------------------------------------------------------------------------
class THsuanluTest1 : public THsuanluBase
{
public:
virtual void PrintMessage(void){ Form1->Memo1->Lines->Add(L"这是 THsuanluTest1 的 PrintMessage 方法"); }
};
//---------------------------------------------------------------------------
class THsuanluTest2 : public THsuanluBase
{
public:
virtual void PrintMessage(void){ Form1->Memo1->Lines->Add(L"这是 THsuanluTest2 的 PrintMessage 方法"); }
};
//---------------------------------------------------------------------------
class THsuanluTest3 : public THsuanluTest2
{
public:
virtual void PrintMessage(void){ Form1->Memo1->Lines->Add(L"这是 THsuanluTest3 的 PrintMessage 方法"); }
};
- 定义 HsuanluFactory 时,由于自己写的这些类的构造函数没有参数,所以模板参数只有一个公共父类 THsuanluBase
- 在程序开始执行的时候,即主窗口的构造函数里面注册所有需要反射的类,然后就可以使用类名字符串来创建这些类的对象了。
THsuanluReflectionFactory HsuanluFactory;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
HsuanluFactory.Register();
HsuanluFactory.Register();
HsuanluFactory.Register();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
THsuanluBase *p1 = nullptr, *p2 = nullptr, *p3 = nullptr;
try
{
p1 = HsuanluFactory.Create(L"THsuanluTest1");
p2 = HsuanluFactory.Create(L"THsuanluTest2");
p3 = HsuanluFactory.Create(L"THsuanluTest3");
p1->PrintMessage();
p2->PrintMessage();
p3->PrintMessage();
}
catch(Exception &e)
{
ShowMessage(e.Message);
}
delete p1;
delete p2;
delete p3;
}
运行结果:
相关:
- C++ Builder 的反射 (三) - 通用 Reflection Factory
- C++ Builder 的反射 (一) - Reflection 简单实现
- C++ Builder 获取任意一个类或对象的类名
- 枚举控件所有的属性、事件和方法
- 枚举窗口内所有的控件
- C++ Builder 的枚举类型
- C / C++ 可变参数的函数
- C / C++ 可变参数的宏,__VA_ARGS__,...
- C++ 可变参数的模板
- C++ Builder 的 PME 架构
C++ Builder 参考手册 ➙ C++ Builder 的反射 (二) - Reflection Factory