當前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]前面我們說過,Qt 不是使用的“標準的” C++ 語言,而是對其進行了一定程度的“擴展”。這里我們從Qt新增加的關(guān)鍵字就可以看出來:signals、slots 或者 emit。所以有人會覺得 Qt 的

前面我們說過,Qt 不是使用的“標準的” C++ 語言,而是對其進行了一定程度的“擴展”。這里我們從Qt新增加的關(guān)鍵字就可以看出來:signals、slots 或者 emit。所以有人會覺得 Qt 的程序編譯速度慢,這主要是因為在 Qt 將源代碼交給標準 C++ 編譯器,如 gcc 之前,需要事先將這些擴展的語法去除掉。完成這一操作的就是 moc。

moc 全稱是 Meta-Object Compiler,也就是“元對象編譯器”。Qt 程序在交由標準編譯器編譯之前,先要使用 moc 分析 C++ 源文件。如果它發(fā)現(xiàn)在一個頭文件中包含了宏 Q_OBJECT,則會生成另外一個 C++ 源文件。這個源文件中包含了 Q_OBJECT 宏的實現(xiàn)代碼。這個新的文件名字將會是原文件名前面加上 moc_ 構(gòu)成。這個新的文件同樣將進入編譯系統(tǒng),最終被鏈接到二進制代碼中去。因此我們可以知道,這個新的文件不是“替換”掉舊的文件,而是與原文件一起參與編譯。另外,我們還可以看出一點,moc 的執(zhí)行是在預(yù)處理器之前。因為預(yù)處理器執(zhí)行之后,Q_OBJECT 宏就不存在了。

既然每個源文件都需要 moc 去處理,那么我們在什么時候調(diào)用了它呢?實際上,如果你使用 qmake 的話,這一步調(diào)用會在生成的 makefile 中展現(xiàn)出來。從本質(zhì)上來說,qmake 不過是一個 makefile 生成器,因此,最終執(zhí)行還是通過 make 完成的。

為了查看 moc 生成的文件,我們使用一個很簡單的 cpp 來測試:

test.cpp

class?Test?:?public?QObject?
{?
?Q_OBJECT?
public:?
?explicit?Test(QObject?*parent?=?0);?
signals:?
public?slots:?
};

這是一個空白的類,什么都沒有實現(xiàn)。在經(jīng)過編譯之后,我們會在輸出文件夾中找到 moc_test.cpp:

moc_test.cpp

/****************************************************************************?
**?Meta?object?code?from?reading?C++?file?'test.h'?
**?
**?Created:?Thu?Jul?22?13:06:45?2010?
**??????by:?The?Qt?Meta?Object?Compiler?version?62?(Qt?4.6.3)?
**?
**?WARNING!?All?changes?made?in?this?file?will?be?lost!?
*****************************************************************************/?
?
#include?"../test.h"?
#if?!defined(Q_MOC_OUTPUT_REVISION)?
#error?"The?header?file?'test.h'?doesn't?include."?
#elif?Q_MOC_OUTPUT_REVISION?!=?62?
#error?"This?file?was?generated?using?the?moc?from?4.6.3.?It"?
#error?"cannot?be?used?with?the?include?files?from?this?version?of?Qt."?
#error?"(The?moc?has?changed?too?much.)"?
#endif?
?
QT_BEGIN_MOC_NAMESPACE?
static?const?uint?qt_meta_data_Test[]?=?{?
?
?//?content:?
???????4,???????//?revision?
???????0,???????//?classname?
???????0,????0,?//?classinfo?
???????0,????0,?//?methods?
???????0,????0,?//?properties?
???????0,????0,?//?enums/sets?
???????0,????0,?//?constructors?
???????0,???????//?flags?
???????0,???????//?signalCount?
?
???????0????????//?eod?
};?
?
static?const?char?qt_meta_stringdata_Test[]?=?{?
????"Test