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

main.cpp

#include "animal.h"
#include <QCoreApplication>
#include <QDebug> 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<Animal*>(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*>()来达到效果。

https://blog.csdn.net/kenier/article/details/62041312 

Qt类反射机制的更多相关文章

  1. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  2. 深入Qt 学习 -- 反射机制(比较简单清楚)

    相对于Java天生的这一特性, C++并不具备;但进入到Qt领域,这一切都变得简单自如了. 从Qt的元对象系统可知,除了提供信号/槽机制的特性之外,它还提供了以下特性: ■ QObject::meta ...

  3. Qt之类反射机制

    在java语言中,可以使用getObject(String)函数,从类型直接构建新的对象. 而在C++中是没有这种机制的,Qt虽然提供了元对象机制,但只可以获取对象的类名,不能反向构建. 所以搜索一下 ...

  4. Qt5之反射机制(内省)

    Qt的元对象系统除了提供信号/槽机制的特性之外,它还提供了以下特性: QObject::metaObject() 返回关联的元对象 QMetaObject::className() 在运行时状态下返回 ...

  5. ReflectUitls类的编写和对反射机制的解析

    ReflectUitls类的编写和对反射机制的解析 反射相关的类 反射相关的类,最基本的当然是Class类. 获取了Class对象之后,就可以接着生成对象实例.调用方法.查看字段等等. 字段(Fiel ...

  6. java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。

    首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一.  类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...

  7. Java通过反射机制修改类中的私有属性的值

    首先创建一个类包含一个私有属性: class PrivateField{ private String username = "Jason"; } 通过反射机制修改username ...

  8. c#反射机制判断同一个类的两个实例的值是否完全一样

    ; i < properties1.Length; i++)            {                string s = properties1[i].DeclaringTyp ...

  9. 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换

    作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...

随机推荐

  1. 获取web.py上面的示例code

    import requests import re import os.path #取得文件名和内容对应字典 def getCode(url): pattern=re.compile(r'<h\ ...

  2. [转] copy_to_user和copy_from_user两个函数的分析

    在内核的学习中会遇到很多挺有意思的函数,而且能沿着一个函数扯出来很多个相关的函数.copy_to_user和copy_from_user就是在进行驱动相关程序设计的时候,要经常遇到的两个函数.由于内核 ...

  3. 菜单下拉效果demo记录

    <!doctype html> <html> <head> <meta http-equiv="Content-Type" content ...

  4. Firefly 性能测试 通报

    http://bbs.gameres.com/forum.php?mod=viewthread&tid=220516 Firefly 性能测试 主要考虑点 网络IO的并发 进程间通信压力 数据 ...

  5. 解决树莓派新内核无法使用18B20和没有声音的问题

    现在新版的树莓派内核由于为了兼容树莓派2和树莓派B+等以前的版本,采用了和原来不同的内核运行方式,使用了设备树的方式,更加灵活.但是由于可能不习惯这样的方式以及没太多相关这方面的介绍,导致很多用户更新 ...

  6. 准备你的Adempiere开发环境(2)- 安装

    1. 用pgAdmin III创建用户adempiere/adempiere:2. 创建adempiere360数据库:3. 导入<ADEMPIERE_HOME>\data\Adempie ...

  7. 一个官翻教程集合:ASP.NET Core 和 EF Core 系列教程

    通过一个大学课程案例讲解了复杂实体的创建过程及讲解 1.ASP.NET Core 和 Entity Framework Core 系列教程——入门 (1 / 10) 2.ASP.NET Core 和 ...

  8. Service stopSelf(int statId)和onStartcommand(Intent intent,int flags,int startId)

    Stopping a service A started service must manage its own lifecycle. That is, the system does not sto ...

  9. 关于Go语言daemon启动的方法.

    昨天搞了个文件共享的小程序,遇见了意见蛋疼的事,就是启动之后终端不能关闭,不然程序也会随着关闭. 我的解决方法: nohup ./httpserver & nohup这个命令能够把程序放后台执 ...

  10. centos(7.0) 上 crontab 计划任务

    yum install vixie-cron yum install crontabs /bin/systemctl restart crond.service  #启动服务 /bin/systemc ...