元对象

使用反射机制获取类对象成员函数的信息

a.h文件:

//头文件 a.h 的内容(文件读者自行创建)
#ifndef A_H //要使用元对象系统,需在头文件中定义类。
#define A_H
#include<QObject> //因为要使用 QObject 类,为此需要包含此头文件

class A:public QObject{
    Q_OBJECT //启动元对象系统,必须声明此宏
public:
    //定义 2 个构造函数、1 个信号、3 个函数。
    Q_INVOKABLE A(){} //要想函数被反射,需要指定 Q_INVOKABLE 宏。
    Q_INVOKABLE A(int){}
    Q_INVOKABLE void f(){}
    Q_INVOKABLE void g(int i,float j){}
    void g1(){} //注意:此函数不会被反射
signals:
    void gb3();
};

class B:public A{
    Q_OBJECT //要使用元对象系统,应在每个类之中都声明此宏
public:
    //定义 1 个函数、2 个信号
    Q_INVOKABLE void f(){}
signals:
    void gb4();
    void gb5();
};

#endif // A_H

 main.cpp文件:

#include "a.h"
#include <QMetaMethod>
#include <QByteArray>
#include <iostream>
using namespace std;

int main(){
    A ma; B mb; //创建两个对象
    const QMetaObject *pa=ma.metaObject();
    const QMetaObject *pb=mb.metaObject();
    
    //以下为通过 QMetaObject 的成员函数获取的信息。
    int j=pa->methodCount(); /*返回对象 ma 中的成员函数数量,包括从父类 QObject 继承而来的 5 个
                                成员函数及本对象中的 2 个成员函数(注意,不包括 g1)、1 个信号,所以
                                总数为 8。*/
    cout<<j<<endl; //输出 8
    
    int i=pa->indexOfMethod("g(int,float)"); //获取对象 ma 中的成员函数 g 的索引号。
    cout<<i<<endl; //输出 7
    
    i=pa->constructorCount(); //获取对象 ma 所属类中的构造函数的数量。
    cout<<i<<endl; //输出 2
    
    i=pb->constructorCount(); /*获取对象 mb 所属类 B 中的构造函数的数量,因类 B 无构造函数,所以
                                返回值为 0,此处也可看到,构造函数数量不包含父类的构造函数*/
    cout<<i<<endl; //输出 0。
    
    i=pa->indexOfConstructor("A(int)"); //获取对象 ma 所属类中的构造函数 A(int)的索引号。
    cout<<i<<endl; //输出 1。
    
    i=pa->indexOfSignal("gb3()"); //获取对象 ma 的信号 gb3()的索引号。
    cout<<i<<endl; //输出 5。
    
    i=pa->indexOfSignal("f()"); /*获取对象 ma 的信号 f()的索引号。因为成员函数 f 存在,但不是信
                                 号,所以返回值为-1。*/
    cout<<i<<endl; //输出-1。
    
    i=pb->methodOffset(); /*获取父类的成员函数数量,包括父类A及QObject中的成员函数,总共为8。*/
    cout<<i<<endl; //输出 8,此处相当于是对象 mb 自身成员函数开始处的索引号。
    
    //以下为通过 QMetaMethod 的成员函数获取的信息。
    //获取对象 ma 的成员函数 g 的元数据。
    QMetaMethod m=pa->method(pa->indexOfMethod("g(int,float)"));
    QByteArray s= m.name(); //获取成员函数 g 的函数名。
    cout<<s.data()<<endl; //输出 g
    s=m.methodSignature(); //获取函数 g 的签名
    cout<<s.data()<<endl; //输出 g(int,float)
    i=m.methodType(); /*获取函数 g 的类型,此处返回的是 QMetaMethod::MethodType 中定义的枚举值,
                        其中 Method=0,表示类型为成员函数*/
    cout<<i<<endl; //输出 0(表示成员函数)。
    
    //以下信息与函数的返回类型有关
    s=m.typeName(); //获取函数 g 的返回值的类型名
    cout<<s.data()<<endl; //输出 void
    i=m.returnType(); /*获取函数 g 返回值的类型,此处的类型是 QMetaType 中定义的枚举值,其中枚举
                        值 QMetaType::void=43*/
    cout<<i<<endl; //输出 43
    i=m.parameterType(1); /*获取函数 g 中索引号为 1 的参数类型,此处的类型是 QMetaType 中定义的
                            枚举值,其中枚举值 QMetaType::float=38*/
    cout<<i<<endl; //输出 38
    
    QList<QByteArray> q=m.parameterNames(); //获取函数 g 的参数名列表
    cout<<q[0].data()<<q[1].data()<<endl; //输出 ij
    q=m.parameterTypes(); //获取函数 g 的参数类型列表。
    cout<<q[0].data()<<q[1].data()<<endl; //输出 int float
    return 0;
}

使用反射机制获取与类相关的信息

b.h文件:

#ifndef B_H
#define B_H

#include<QObject>

class A:public QObject{ Q_OBJECT};
class B:public A{ Q_OBJECT };
class C:public QObject{Q_OBJECT};
class D:public C{};

#endif // B_H

main.cpp文件:

void fun_2()
{
    A ma; B mb; C mc; D md;
    const QMetaObject *pa=ma.metaObject();
    const QMetaObject *pb=mb.metaObject();

    cout<<pa->className()<<endl; //输出类名 A

    //使用 QMetaObject::inherits()函数判断继承关系。
    cout<<pa->inherits(pa)<<endl; //输出 1,类被认为是自身的子类
    cout<<pa->inherits(pb)<<endl; //输出 0,由 pb 所描述的类 B 不是类 A 的子类。
    cout<<pb->inherits(pa)<<endl; //输出 1,由 pa 所描述的类 A 是类 B 的子类。

    //使用 QObject::inherits()函数判断继承关系。
    cout<<ma.inherits("B")<<endl; //输出 0,类 A 不是类 B 的子类。
    cout<<ma.inherits("A")<<endl; //输出 1,类被认为是自身的子类
    cout<<md.inherits("D")<<endl; //输出 0,因为类 D 未启动元对象系统。
    cout<<md.inherits("C")<<endl; /*输出 1,虽然类 D 未启动元对象系统,但类 C 已启动,此种情形下
                                    能正确判断继承关系。*/
    cout<<md.metaObject()->className()<<endl; /*输出 C,此处未输出 D,因为类 D 未启动元对象系统,
                                    与类 D 最接近的启动了元对象系统的父类是 C,因此返回 C。*/
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柔弱胜刚强.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值