所谓反射,就是指对象成员的自我检查,使用反射编程就可以编写出通用的操作,可对具有各种不同结构的类进行操作;
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宏的后面;