元对象、 属性 和 反射编程

所谓反射,就是指对象成员的自我检查,使用反射编程就可以编写出通用的操作,可对具有各种不同结构的类进行操作;

Qt使用通用的值存储器QVariant,就可以按照一种统一的方式来对基本类型和其他普通类型进行操作;

QMetaObject  ---- 元对象模式

元对象,就是描述另一个对象结构的对象;

QMetaObject是元对象模式(MetaObject Pattern)的一个Qt实现,他提供一个QObject对象拥有的属性和方法的信息。

     一个拥有元对象的类就可以支持反射,这是一个许多面向对象语言都具有的性质; 虽然C++不存在反射,但是Qt的元对象编译器(moc)可以为QObject生成支持这种机制的代码;

 

 QObject拥有一个成员函数,他能够返回指向对象的QMetaObject的指针.这个函数原型:

   QMetaObject * QObject::metaObject() const [virtual]

 

 

QMetaObject 提供以下方法:

className():   将类的名称以const char*格式返回;

superClass():  如果存在基类的QMetaObject,则返回其指针(如果不存在,则返回0)

     methodCount(): 返回类的成员函数的个数;

类型识别 和 qobject_cast


  RTTI 全称 Run Time Type Identification(运行时类型识别),如同起名字显示一样,是一个用来在运行时决定一个你可能仅仅拥有其基类指针的对象的实际类型的系统

除了C++ 提供的dynamic_case 和 typeid    Qt提供了 两种运行时的类型识别机制

   qobject_cast

   QObject::inherits(); //  Qt 不再建议使用、java风格的类型检查函数; inherits()按树接受一个char * 类型名,而不是类型表达式。因为该运算符需要额外的哈希表查找操作,所以该函数逼Qobject_cast要慢一些;

  

qobject_cast是一个ANSI风格的类型转换运算符.ANSI类型转换看来很像模板函数:

     DestType* qobject_cas<DestType*>(QObject* qoptr)

   类型转换运算符根据类型和语言的特定规则与约束将表达式从一种类型转化为另一种类型.

 

   qobject_cast 把目标类型看做模板参数,他返回指向同一个对象的DestType的指针; 如果在运行时,实际的指针类型无法转化成DestType* 那么转换就会失败,此时返回值是NULL;

qobject_cast 实际上是一个向下转换的运算符,类似与dynamic_cast。qobject_cast允许把一个更为常规的指针和引用转换成某种特定的类型;

   qobject_cast 的运行速度 要比 dynamic_cast 块5到10倍;(取决与使用的编译器)

   拥有指向派生类的基类指针时,向下转化允许调用在基类接口中不存在的派生类方法;;;(转化称为派生类指针对象,调用派生类函数)(qobject_cast的实现没有使用C++ RTTI,该运算符的元对象编译器生成的)

  把qobject_cast用于非QOBject的基类时,需要把每个基类都放到一个形如Q_INTERFACES(BaseClass1 BaseClass2)的代码行内,并把它放到类定义中,Q_OBJECT宏的后面;

时间: 2024-10-24 14:16:20

元对象、 属性 和 反射编程的相关文章

Qt元对象(Meta-Object)系统与反射

反射 -在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问.检测和修改它本身状态或行为的一种能力.[1]用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为. 要注意术语“反射”和“内省”(type introspection)的关系.内省(或称“自省”)机制仅指程序在运行时对自身信息(称为元数据)的检测:反射机制不仅包括要能在运行时对程序自身信息进行检测,还要求程序能进一步根据这些信息改变程序状态或结构. C++的反射 C++的标准语法是不提供反射的特性的,不

java反射获取对象的属性值和对象属性中的子属性值

近段时间在做web项目,前端使用的是jQuery EasyUI. 为方便需要,准备做一个前端通用的Datagird导出Excel功能,博主也考虑过思路和最终功能,1.前端选中行导出:2.当前页导出:3.当前过滤条件导出. 想偷懒在网上找找已有的代码改改,发现大部分只能满足个别需求,使用JS导出只能满足前端,使用代码才能实现3功能. ...... 好了,说了一堆废话,回归正题,本文是在做通用自定义字段导出时所需要,根据属性名去查找对象和子对象,找到对应属性值,抓取回来放到Excel中. 直接上代码

泛型约束和利用反射修改对象属性的值

周日了都,昨天休息了一天,今天想想得敲敲代码练习一下,如下关于泛型约束和利用反射修改对象属性的值的, 都挺简单的,呵呵,但时间一长,不经常使用还容易忘记在此就当记录一下了, 首先泛型代码一般是如下的情形: 加了泛型约束,只允许引用类型并且是只能是无参数的构造函数的类型才能传入,也就是不允许给类构造参数传递实参,否则将报错. 错误 1 “XXXXXX.pros”必须是具有公共的无参数构造函数的非抽象类型,才能用作泛型类型或方法“ 1 public static T GetObject<T>(T

复制对象属性:只复制需要的属性值,目标对象中原来的值不变(反射)

使用反射(性能很差,自测是cglib-beanmap性能的50分之1左右): /** * 复制对象属性:只复制需要的属性值,目标对象中原来的值不变 * 只适用于2个相同对象 * @param from 要复制的对象 * @param to 目标对象 * @throws Exception */ @SuppressWarnings("unchecked") public static void copyPropertiesExclude(Object from, Object to) t

C#利用反射获取对象属性值

public static string GetObjectPropertyValue<T>(T t, string propertyname){     Type type = typeof(T); PropertyInfo property = type.GetProperty(propertyname); if (property == null) return string.Empty; object o = property.GetValue(t, null); if (o == n

c#设置对象属性——反射实体设置变量

前台如果只传递了一两个数据,在后台请求获取数据设置属性值还能够接受,但是如果传递了大量的数据,就得多次HttpRequest reques[“XXX”]请求获取数据设置属性值,输入的代码量就很大,而且相当耗费时间,这种费时费力的方法是难以接受的.下面为大家提供一个取巧的方法,获取请求数据就变的很简单了,而且可以节省时间.话不多说,直接上代码: C#代码如下: /// <summary> /// 设置对象属性——反射实体设置变量 /// </summary> /// <para

Qt根据类获取对象(元对象反射)

在java语言中,可以使用getObject(String)函数,从类型直接构建新的对象. 而在C++中是没有这种机制的,Qt虽然提供了元对象机制,但只可以获取对象的类名,不能反向构建. 这个问题我在百度上找了很多,但都没有满意的答案,索性翻出去google一下,终于找到了解决方法. 原文地址:http://www.mimec.org/node/350 代码如下: objectfactory.h #include <QByteArray> #include <QMetaObject>

(远程方法的调用)对象序列化、反射在网络编程的运用

对象的序列化与反序列化[p213页]当两个进程进行远程通信时,彼此可以发送各种类型的数据,如文本.图 片.语音和视频等.无论不纯二进制序列的形式在网络上传送.当两个 java进程进行远程通信时,一个进程把一个java对象发送到另一个进程 中.不过发送方需要把这个java对象转换为字节序列,才能在网络上传 送:接收方则需要把自己序列在恢复为java对象.把java对象转换为字 节序列的过程称为对象序列化:把字节序列恢复为java对象的过程称为 对象称为对象的反序列化.JDK类库中的序列化APIja

JavaScript服务器编程(对象属性枚举中应当避免原型污染问题)

前面文章中讨论了JS开发中对象属性枚举的ES3和ES5方案并给出了一组常用工具函数,其实,企业开发中真正应用时还存在不少问题.本文想基于前文进一步探讨一下有关原型污染的问题.由于JS的先天不足,有关原型污染背后隐藏着一个大的"故事",以后我们的文章中还要涉及其中一些情节. 问题 前面在讨论使用in运算符检测对象中是否存在属性的方案,但是通过所举的示例也发现一个问题,例如: console.log('"ID" in contacts: ',"ID"