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

1、QMetaMethod 类

①、作用:用于描述对象的成员函数,可使用该类的成员函数获取对象成员函数的信息。
②、该类拥有如下成员:
 enum MethodType{Method, Signal, Slot, Constructor}
此枚举用于描述函数的类型,即:普通成员函数(Method)、信号(Signal)、槽(Slot)、构
造函数(Constructor)。
 enum Access{Private, Protected, Public}
此枚举主要用于描述函数的访问级别(私有的、受保护的、公有的)
 QByteArray methodSignature() const; //返回函数的签名(qt5.0)
 MethodType methodType() const; //返回函数的类型(信号、槽、成员函数、构造函数)
 QByteArray name() const; //返回函数的名称(qt5.0)

int parameterCount() const ; //返回函数的参数数量(qt5.0)
 QList<QByteArray> parameterNames() const; 返回函数参数名称的列表。
 int parameterType(int index) const;
返回指定索引处的参数类型。返回值是使用QMetaType 注册的类型,若类型未注册,
则返回值为QMetaType::UnknownType。
 QList<QByteArray> parameterTypes() const; 返回函数参数类型的列表。
 int returnType() const;
返回函数的返回类型。返回值是使用QMetaType 注册的类型,若类型未注册,则返
回值为QMetaType::UnknownType。
 const char * typeName() const; 返回函数的返回类型的名称。
 Access access() const; 返回函数的访问级别(私有的、受保护的、公有的)

2、QMetaObject 类中有关获取类对象成员函数的函数有:

①、int indexOfMethod(const char* f) const;
返回名为 f 的函数的索引号,否则返回-1。此处应输入正确的函数签名,比如函数形

式为void f(int i,int j);则正确的形式为xx.indexOfMethod("f(int,int"); 以下形式都不是
正确的形式,"f(int i, int j)"、"void f(int, int)"、"f"、"void f"等。
②、int indexOfSignal(const char * s) const;
返回信号s 的索引号,否则返回-1,若指定的函数存在,但不是信号,仍返回-1。
③、int indexOfConstructor(const char *c) const; //返回构造函数c 的索引号,否则返回-1
④、int constructorCount() const ; //返回构造函数的数量。
⑤、QMetaMethod constructor(int i)const; 返回指定索引i 处的构造函数的元数据。
⑥、int methodCount() const;
返回函数的数量,包括基类中的函数、信号、槽和普通成员函数。
⑦、int methodOffset() const;
返回父类中的所有函数的总和,也就是说返回的值是该类中的第一个成员函数的索
引位置。
⑧、QMetaMethod method(int i) const; 返回指定索引 i 处的函数的元数据。

 

#ifndef M_H //要使用元对象系统,需在头文件中定义类。
#define M_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 // M_H
#include "m.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 自身成员函数开始处的索引号。
//以下为通过QMetaMethon 的成员函数获取的信息。
//获取对象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; //输出intfloat
return 0; 
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

fyzy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值