博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt类反射机制
阅读量:5996 次
发布时间:2019-06-20

本文共 2010 字,大约阅读时间需要 6 分钟。

前言
 
如何通过类名动态的创建对象(类反射),对于Java开发者来说一点也不陌生,当然Qt也提供了一个元对象系统(The Meta-Object System),通过这个系统我们可以动态的在运行时获取一个类的构造函数、方法、字段、枚举等信息。但奇怪的是Qt文档中并没有提供类似于Java中Class.forName之类的方法,即类反射机制。经过网上查阅资料,发现大多数人实现此功能的方式都是自定义一个对象工厂(ObjectFactory)以模版的方式来实现的。后来我仔细阅读Qt文档,发现了Qt自带的类反射机制
 
实现
animal.h
#ifndef ANIMAL_H#define ANIMAL_H#include 
class Animal : public QObject{ Q_OBJECTpublic: explicit Animal(QObject *parent = 0); virtual QString name() const = 0;};#endif // ANIMAL_H

animal.cpp

#include "animal.h"Animal::Animal(QObject *parent) : QObject(parent){}

person.h

#ifndef PERSON_H#define PERSON_H#include "animal.h"class Person : public Animal{    Q_OBJECTpublic:    static int typeId;    Q_INVOKABLE explicit Person(const QString &name, QObject *parent = 0);    QString name() const;private:    QString m_name;};#endif // PERSON_H

person.cpp

#include "person.h"int Person::typeId = qRegisterMetaType
();Person::Person(const QString &name, QObject *parent) : Animal(parent) , m_name(name){}QString Person::name() const{ return m_name;}

main.cpp

#include "animal.h"#include 
#include
int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); int type = QMetaType::type("Person*"); const QMetaObject *metaObj = QMetaType::metaObjectForType(type); QObject *obj = metaObj->newInstance(Q_ARG(QString, QStringLiteral("Rex")), Q_ARG(QObject*, nullptr)); Animal *an = qobject_cast
(obj); qDebug().noquote() << an->name(); return a.exec();}
Animal是一个虚基类,它有一个纯虚函数name,Person继承Animal并重写了name,一个非常简单的多态列子。可以看到在main.cpp中并没有包含Person类的头文件,仅仅通过"Person*"这个字符串就获得了Person类的元对象,并通过newInstance调用了Person的构造函数,最后通过qobject_cast把obj向下转型为Animal an,通过an调用虚函数name。
 
需要注意的地方是:Person的构造函数必须声明为Q_INVOKABLE,否则newInstance无法调用该构造函数。另外必须要在main函数执行之前调用qRegisterMetaType<Person*>()注册Person,否则QMetaType::type无法获取Person*的类型ID。因为静态变量始终在main函数执行之前初始化,所以我通过在Person中增加了一个typeId的静态成员变量,在初始化的时候调用qRegisterMetaType<Person*>()来达到效果。

 

转载地址:http://ugmlx.baihongyu.com/

你可能感兴趣的文章
SQL Server 审核(Audit)-- 介绍
查看>>
SQL Server 2016:内存列存储索引
查看>>
立项申请书模板
查看>>
C#提高知识 ADO.NET实体数据模型(1)
查看>>
送给那些搞电脑维修的人儿
查看>>
linux基础概念和个人笔记总结(3)
查看>>
Exchange Server 2013预览版服务器角色概况
查看>>
IPSec ***和SSL ***两种***的安全风险比较
查看>>
智能设备:用户隐私丛林,恶意应用淘金地
查看>>
Hadoop入门扫盲:hadoop发行版介绍与选择
查看>>
实战1:创建Windows Server 2008域
查看>>
在 Windows 2012 R2 安装 SharePoint 2013
查看>>
《统一沟通-微软-实战》-6-部署-5-边缘服务器-2012-07-12-3
查看>>
活动目录域控制器最长可以离线多久?
查看>>
红帽转型为云计算解决方案提供商
查看>>
疯狂ios之cocos2d中的文本
查看>>
Mac下通过 brew 安装不同版本的php
查看>>
云在天之南——我的七天七夜(率性苍山洱海)
查看>>
如何迅速入门Shell 编程
查看>>
Linux企业应用微博客正式开通
查看>>