美文网首页
QT实现反射

QT实现反射

作者: pandazhong | 来源:发表于2018-12-11 15:46 被阅读0次

前言

如何通过类名动态的创建对象(类反射),对于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*>()来达到效果。

相关文章

  • QT实现反射

    前言 如何通过类名动态的创建对象(类反射),对于Java开发者来说一点也不陌生,当然Qt也提供了一个元对象系统(T...

  • QT 反射机制的简单使用

    Qt反射前期准备 [以下内容来自博客# Qt5之反射机制(内省),转载请注意说明出处] 首先得继承于Q_Objec...

  • Qml动态语言切换

    此方法需要在Qt5.10或更高版本实现, 在Qt5.10或更高版本实现, 在Qt5.10或更高版本实现重要的事情说...

  • C++中使用QT实现反射机制

    1.反射机制 反射机制在java中是一个非常重要的特性,JAVA反射机制是在运行状态中,对于任意一个类,都能够知道...

  • Qt开发技术分享之Http Multipart上传文件到Java

    通过 Qt 来实现来上传文件相对麻烦一点,参考Qt 官方简单例子[https://doc.qt.io/archiv...

  • QtXlsx

    QT/QT5.15+VS2019配置QtXlsx实现读写Excel文件[https://blog.csdn.net...

  • Deepin15.10.1搭建PyQt5/PySide2环境(基

    PyQt5/PySide2是Qt环境的python实现,Qt可以实现跨平台的GUI编程。PyQt5/PySide2...

  • Qt学习-(基础)

    Qt学习 Qt是什么 Qt是一个跨平台的C++图形用户界面库,通过变以来跨平台,实现一个Qt支持Unix,Linu...

  • Java获取反射的三种方法

    1.通过new对象实现反射机制 2.通过路径实现反射机制 3.通过类名实现反射机制 public class Ge...

  • 说说QT

    QT项目在2015年就已经提出,项目最终目标即是实现QT(七天)库存。 对于怎么实现,不知高层是否有过专门的解读,...

网友评论

      本文标题:QT实现反射

      本文链接:https://www.haomeiwen.com/subject/adhehqtx.html