注意Qt的元对象系统。。

1、转自百度百科


Qt 元对象系统(Meta-Object System)
Qt的元对象系统基于如下三件事情:
1. 类:QObject,为所有需要利用元对象系统的对象提供了一个基类。

2. 宏:Q_OBJECT,通常可以声明在类的私有段中,让该类可以使用元对象的特性,比如动态属性,信号和槽。

3. 编译器:元对象编译器(moc)为每个QObject子对象自动生成必要的代码来实现元对象特性。
moc工具会读入C++的源文件,如果它发现了一个或者多个声明了Q_OBJECT宏的类,它就创建另一个C++源文件,为每个类生成包含元对象实现的代码。这些编译生成的源文件通常都已经被包含到类的源文件中或者和类的实现同时被编译和链接。
除了为对象间的通信提供信号和槽(signals and slots)机制之外,元对象的代码还提供下列特性:
· QObject::metaObject()返回与该类绑定的meta-object对象。
· QMetaObject::className()可以在运行时以字符串的形式返回类的名字,不需要C++编译器原生的运行时类型信息(RTTI)的支持。
· QObject::inherits()函数返回继承信息:对象是否是QObject继承树上一个类的实例。
· QObject::tr()和QObject::trUtf8()提供国际化支持,将字符串翻译成指定的语言。
· QObject::setProperty()和QObject::property()通过名字动态设置和获取对象属性。
· QMetaObject::newInstance()构造该类的一个新实例。
除此之外你还可以用qobject_cast()动态转换QObject类的类型。qobject_cast()函数和标准C++的dynamic_cast()功能类似,只是其不需要RTTI的支持,而且可以跨越动态连接库的边界。它尝试将它的参数cast成尖括号内的对象类型,如果对象是正确的类型(运行时决定)则返回非零,否则返回0,说明对象类型不兼容。
例如,假设MyWidget继承自QWidget,同时也声明了Q_OBJECT宏,
QObject *obj = new MyWidget;QObject类型的变量obj实际上指向一个MyWidget对象,因此我们可以这样进行类型转换:
QWidget *widget = qobject_cast<QWidget *>(obj);到MyWidget的转型可以成功是因为qobject_cast()并没有对Qt内建对象和定制的扩展对象分别对待。
QLabel *label = qobject_cast<QLabel *>(obj); // label is 0另一方面到QLabel的转型则会失败,指针会被设置为0。这样使得我们可以在运行时根据对象类型,对不同类型的对象进行不同的处理:
if (QLabel *label = qobject_cast<QLabel *>(obj)) { label->setText(tr("Ping")); } else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) { button->setText(tr("Pong!")); }尽管我们可以在不用Q_OBJECT宏和原对象信息的情况下仍旧使用QObject作为基类,但是像信号和槽以及其他这里描述的特性将无法使用。从元对象系统的观点来看,一个没有元对象代码的QObject子类和其最接近的有元对象代码的祖先是等同的。这也就意味着,QMetaObject::className()将不会返回你的类的真实的名字,而是该类某一个祖先的名字。
因此,我们强烈建议所有QObject的子类都是用Q_OBJECT宏,不管你实际上是否使用信号和槽,以及属性




2、下面的是转自C++ GUI Qt4编程(第二版)P17


qt的主要成就之一就是使用了一种机制对C++进行了扩展,并且使用这种机制创建了独立的软件组件,这些组件可以绑定在一起,但任何一个组件对于它所要连接的组件的情况一无所知,


        这种机制就称为元对象系统,它提供了关键的两个技术,信号和槽,以及内省。


        内省功能对于实现信号和槽是必须的,并且容许开发人员在运行时获取有关QObject子类的“元信息”,包括一个含有对象的类名以及它所支持的信号和槽的列表,这一机制也支持属性和文本翻译,并且为Qtscript模块奠定了基础,


        标准的C++没有对qt的的元对象系统锁需要的动态元信息提供支持,qt是通过一个独立的moc工具解决这个问题,moc解析Q_OBJECT类的定义并且通过c++函数来提供可供使用的信息,犹豫moc使用纯c++来实现所有功能,所以qt的元对象系统可以在任意c++编译器上工作。


 这一机制是这样工作的:


       Q_OBJECT宏声明了每一个QObject子类中必须实现的一些内省函数:metaobject,tr(),qt_metacall(),以及一些其它函数。


        Qt的moc工具生成了用于由Q_OBJECT声明的所有函数和所有信号的实现。


  像connect()和disconnnect()这样的QOBJECT成员函数使用这些内省函数来完成他们的工作。


    这些工作都是由qmake,moc和QObject自动处理的,所以很少需要再去考虑这些事情,如果好奇可以参考QMetaObject类的文档和由moc生成的c++源代码文件。

你可能感兴趣的:(C++,qt,qt,调试,makefile,cpp)