Qt中Meta-Object的重要性和使用原理


Meta-Object系统为我们提供了信号-槽机制、运行期类型信息和动态属性系统。

 

Meta-Object系统是基于以下三点才能正常运行的:

1.      QObject做为一个基类,让派生至它的类能使用到Meta-object系统的各种特性;

2.      在类声明中使用到的宏Q_OBJECT,使得Meta-object系统的各种特性可用;

3.      Meta-Object Compiler(moc)为所有QObject派生类提供了Meta-object特性的实现代码

在编译的时候Moc工具会去读取c++源文件,如果发现类声明中包含了宏Q_OBJECT,它会自动生成另外一份c++源文件,为每一个添加Meta-object的实现代码

 

除了提供信号-槽机制,Meta-object代码还提供了以下几点特性:

1.      QObject::MetaObject()返回这个类所关联的Meta-object;

2.      QMetaObject::className()在运行期以字符串的形式返回类的名称,没有使用c++编译器自带的RTTI;

3.      QObject::inherits()判断一个对象的类是否派生至另一个类;

4.      QObject::tr()和QObject::trUtf8()在国际化中用来翻译字符串

5.      QObject::setproperty()和QObject::property()通过名称动态的设置或获取属性

6.      QMetaObject::newInstance()构造一个类的新的实例;

 

我们还可以使用qobject_cast()来对QObject类进行动态强转。Qobject_cast()方法的作用和标准c++中的dynamic_cast()很相似,但是它没有使用RTTI,并且可以跨dll。

 

当然,我们也可以在不添加Q_OBJECT宏和没有Meta-object实现代码的情况下使用一个QObject子类,但是这样的话就没有信号-槽等其他特性可以使用。从Meta-object系统的立场上看,一个没有Meta代码的QObject子类等价于派生层次中离它最近的包含Meta代码父类。也就是说,QMetaObject::className()方法返回的不是这个类的名称,而是它的包含Meta代码父类名称

 

因此,我们强烈建议所有QObject子类都应该使用Q_OBJECT宏,不论你是不是要用信号-槽和属性

相关文章

HTML5和CSS3实现3D展示商品信息的代码
利用HTML5中的Canvas绘制笑脸的代码
Html5剪切板功能的实现
如何通过HTML5触摸事件实现移动端简易进度条
Html5移动端获奖无缝滚动动画实现
关于HTML5和CSS3实现机器猫的代码