Qt编程:通过反射机制实现类名信息动态创建对象技术

news/2024/5/19 4:41:14 标签: 设计模式, 反射

根据类名信息动态创建对象技术,不仅可以降低代码的耦合度和复杂性,还可以实现脚本化编程技术,动态解析创建对象,提高内存利用率和应用程序灵活性。

反射机制框架如下:

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;

}

};

//宏方法声明类,放在待创建类定义的.h文件里面

#define DECLARE_WIDGET_REFLECT(class_name) \

class class_name##Helper; \  // 前置声明,告诉编译器这个类在他处有定义

extern class_name##Helper class_name##helper; \

//宏方法注册类,放在待创建类方法实现的.cpp中,可确保后面的全局变量不重复定义

#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;

}

注意:这种方式会给每个需要动态创建的类专门定义一个辅助类。

更好的动态创建方式,请见文章:CSDNicon-default.png?t=LA92https://mp.csdn.net/mp_blog/creation/editor/119203142


http://www.niftyadmin.cn/n/1395788.html

相关文章

Ext RAD开发工具预览

Ext官方网站在10月8日放出了RAD开发工具的预览视频&#xff1a; http://www.extjs.com/blog/2009/10/08/ext-js-designer-preview/ 从视频上看&#xff0c;开发Web应用终于可以象VB、Delphi一样&#xff0c;简单轻松了。

Apache HTTP Server 2.2.14 80端口被占用解决

为了使用apache ab 的测试功能&#xff0c;安装Apache HTTP Server 2.2.14,安装发现80端口被占用&#xff0c;由于我的tomcat使用8080&#xff0c;resin使用8088。查看什么程序占用了80端口&#xff0c;把进程kill掉1、Windows平台在windows命令行窗口下执行&#xff1a;D:\>…

应用程序单例化之文件锁

#include <string> #include <iostream> // linux系统 #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include<sys/file.h>/*** brief linux下应用单例化方法之文件锁* param processName 进程名&#xff0c;用于标记唯…

四种在MySQL中修改root密码的方法

整理了以下四种在MySQL中修改root密码的方法,可能对大家有所帮助!方法1&#xff1a; 用SET PASSWORD命令  mysql -u root  mysql> SET PASSWORD FOR rootlocalhost PASSWORD(newpass);方法2&#xff1a;用mysqladmin   mysqladmin -u root password "newpass&qu…

各操作系统各文件系统支持的最大文件的大小

windows操作系统各文件系统支持的最大文件的大小 硬盘格式为&#xff1a;FAT格式&#xff08;如&#xff1a;上世纪的Windows95及之前版本等&#xff09; 单个文件存储容量最大为&#xff1a;4GB 单文件夹中所有文件总和的容量最大为&#xff1a;4GB 单文件夹中最大可有5…

酷易商城开发心得二、缓存应用及个人心得

背景&#xff1a;刚进行完酷易商城网站的编码工作&#xff0c;网站放在服务器上&#xff0c;给大家的第一反应就是"慢"&#xff0c;无论是首页&#xff0c;还是商品详细页面的加载&#xff0c;给人的第一感觉很不好&#xff0c;该能卖东西的让这一慢也把我给吓走了&a…

真正的inotify+rsync实时同步 彻底告别同步慢

背景 我们公司在用inotifyrsync做实时同步&#xff0c;来解决分布式集群文件一致性的问题。但当web文件越来越多(百万级数量html,jpg等小 文件)&#xff0c;同步就越来越慢&#xff0c;根本做不到实时&#xff0c;按照网上的调优方法都尝试过&#xff0c;问题根本没有解决。经过…

系统中毒的现象

最近&#xff0c;好多朋友都说我的QQ游戏不能玩,有时会蓝屏,还有死机,首先和他们进行了硬盘扫描,内存检测都通过了&#xff0c;就怀疑是系统中毒了&#xff0c;给他们重新安装了一下问题解决了。但是但是还有一种问题就是QQ游戏频繁要升级&#xff0c;还有好多补丁和留洞一起要…