【Qt入门实践】Meta-Object的重要性和使用原理

来源:互联网 发布:穆雅斓的淘宝店斌斌 编辑:程序博客网 时间:2024/05/29 13:45


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宏,不论你是不是要用信号-槽和属性。


0 0