Original works, allow reprint, please be sure to use hyperlinks in the form of the original source of the article, author information and this statement. Otherwise, the legal liability will be investigated. http://devbean.blog.51cto.com/448512/355100
As we said earlier, Qt is not a "standard" C + + language, but rather "extended" to a certain extent. Here we can see from the new addition of QT Keywords: signals, slots or emit. So some people would think that Qt's program is slow to compile, mainly because in QT the source code to the standard C + + compiler, such as GCC, prior to the need to remove these extended syntax. The MOC is the way to do this.
The MOC full name is Meta-object Compiler, which is the Meta object compiler. QT programs use the MOC to analyze C + + source files before they are compiled by the standard compiler. If it finds that the macro Q_object is included in a header file, another C + + source file is generated. This source file contains the implementation code for the Q_object macro. This new file name will be preceded by the original filename plus the moc_ composition. This new file will also go into the compilation system and eventually be linked to the binary code. So we can see that this new file is not "replacing" the old file, but is involved in compiling it with the original file. Also, we can see that the MOC is executed before the preprocessor. Because the Q_object macro does not exist after the preprocessor executes.
Since each source file needs to be processed by the MOC, when did we call it? In fact, if you use Qmake, this step call will be shown in the generated makefile. Essentially, Qmake is just a makefile generator, so the final execution is done by make.
To see the files generated by the MOC, we use a very simple CPP to test:
Test.cpp
- Class Test: Public qobject
- {
- Q_object
- Public
- explicit Test (Qobject *parent = 0);
- Signals:
- Public Slots:
- };
This is a blank class and nothing is implemented. After compiling, we will find the Moc_test.cpp in the output folder:
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 (QT 4.6.3)
- **
- * * warning! All changes made in this file would be lost!
- *****************************************************************************/
- #include ". /test.h "
- #if!defined (q_moc_output_revision)
- #error "The header file ' test.h ' doesn ' t include <qobject>."
- #elif q_moc_output_revision! = 62
- #error "This file is generated using the MOC from 4.6.3. It "
- #error "Cannot is 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\0"
- };
- Const Qmetaobject Test::staticmetaobject = {
- {&qobject::staticmetaobject, qt_meta_stringdata_test,
- Qt_meta_data_test, 0}
- };
- #ifdef q_no_data_relocation
- Const Qmetaobject &test::getstaticmetaobject () { return staticmetaobject;}
- #endif//q_no_data_relocation
- Const Qmetaobject *test::metaobject () const
- {
- return Qobject::d _ptr->metaobject? Qobject::d _ptr->metaobject: &staticMetaObject;
- }
- void *test::qt_metacast (const char *_clname)
- {
- if (!_clname) return 0;
- if (!strcmp (_clname, qt_meta_stringdata_test))
- return static_cast<void*> (const_cast< test*> (this));
- return Qobject::qt_metacast (_clname);
- }
- int Test::qt_metacall (Qmetaobject::call _c, int _id, void **_a)
- {
- _id = Qobject::qt_metacall (_c, _id, _a);
- if (_id < 0)
- return _id;
- return _id;
- }
- Qt_end_moc_namespace
As you can see, Moc_test.cpp adds a lot of functions to the test class. However, we do not actually write these functions, how does it join the class? Don't forget, we still have Q_OBJECT this macro! Inside the qobjectdefs.h, find the definition of the Q_object macro:
- #define Q_OBJECT \
- Public: \
- Q_object_check \
- static const qmetaobject staticmetaobject; \
- Q_object_getstaticmetaobject \
- virtual const qmetaobject *metaobject () const; \
- virtual void *qt_metacast (const char *); \
- Qt_tr_functions \
- virtual int Qt_metacall (qmetaobject::call, int, void * *); \
- Private
Here's the idea: it's the expansion of the Q_object macro that allows our Test class to have these extra properties and functions. Note that the Qt_tr_functions macro is also defined here. In other words, if you want to use TR () internationalization, you must use the Q_object macro, otherwise there is no TR () function. The most important thing in this period is virtual Const Qmetaobject *metaobject () const; Function. This function returns an instance of the Qmetaobject meta-object class, through which you gain the ability to reflect the Qt class: Get the type of this object, and all of this does not require the C + + compiler's RTTI support. Qt also provides a function qobject_case () similar to C + + dynamic_cast (), and the implementation of this function does not need to be RTTI. In addition, a class that does not have a Q_object macro defined is the same type as the closest parent class. That is, if a inherits Qobject and defines Q_object,b inherits a but does not define Q_OBJECT,C inherits B, then C's Qmetaobject::classname () function will return a, not its own name. Therefore, to avoid this problem, all classes that inherit the Qobject should define Q_object macros, whether you are using a signal slot or not.
This article is from the "Bean Space" blog, make sure to keep this source http://devbean.blog.51cto.com/448512/355100
Functions of Qmake and MOC (★FIRECAT recommended ★)