根据类名信息动态创建对象技术,不仅可以降低代码的耦合度和复杂性,还可以实现脚本化编程技术,动态解析创建对象,提高内存利用率和应用程序灵活性。
反射机制框架如下:
Reflect类声明如下:
typedef QWidget* (*Constructor)(QWidget* parent);
class Reflect
{
public:
Reflect();
//通过类名,查找到注册的构造函数,并创建对象
static QWidget *reflect(QWidget* parent, const QString& className);
//注册构造函数
static void registerClass(const QString& className, Constructor constructor);
private:
//创建对象工厂
static QWidget* createWidgetFactory(QWidget* parent,const QString& className);
//存储注册的构造方法函数指针
inline static QMap<QString , Constructor>& constructors(){
static QMap<QString , Constructor> _instances;
return _instances;
}
};
//宏方法声明类
#define DECLARE_WIDGET_REFLECT(class_name) \
class class_name##Helper; \
extern class_name##Helper class_name##helper; \
//宏方法注册类
#define IMPL_WIDGET_REFLECT(class_name) \
class class_name##Helper{ \
public: \
class_name##Helper()\
{ \
Reflect::registerClass(#class_name,class_name##Helper::createObjectFunc); \
} \
static QWidget* createObjectFunc(QWidget* parent){ \
return new class_name(parent); \
} \
}; \
class_name##Helper class_name##helper; \
Reflect实现如下
Reflect::Reflect()
{
}
void Reflect::registerClass(const QString& className, Constructor constructor)
{
constructors()[className]=constructor;
}
QWidget *Reflect::createWidgetFactory(QWidget* parent,const QString& className)
{
Constructor constructor=constructors().value(className);
if(constructor){
return (*constructor)(parent);
}
return nullptr;
}
QWidget *Reflect::reflect(QWidget* parent, const QString& className){
return Reflect::createWidgetFactory(parent,className);
}
测试用例类注册:
Form类声明:
```cpp
#include <QLabel>
#include "reflect.h"
class Form : public QLabel
{
Q_OBJECT
public:
explicit Form(QWidget *parent = nullptr);
~Form();
};
DECLARE_WIDGET_REFLECT(Form)
Form实现:
#include "form.h"
Form::Form(QWidget *parent) :
QLabel(parent)
{
setText("通过类名动态创建的画面");
setAlignment(Qt::AlignCenter);
}
Form::~Form()
{
}
IMPL_WIDGET_REFLECT(Form)
测试用例使用
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "reflect.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//通过类名信息动态创建已注册类的对象
setCentralWidget(Reflect::reflect(this,"Form"));
}
MainWindow::~MainWindow()
{
delete ui;
}