Qt中的 #include “xxxx.moc” 说明
在Qt开辟中,有时会看到在cpp文件末尾包含 #include "xxxx.moc" 如许的代码。这种做法重要用于以下环境:
利用场景
当你在非头文件中定义了一个包含Q_OBJECT宏的类时,必要包含对应的.moc文件。重要有两种环境:
- 在.cpp文件中定义的类:假如你在.cpp文件中定义了一个包含Q_OBJECT宏的类(而不是在头文件中),就必要在该.cpp文件末尾包含对应的.moc文件。
- 模板类中利用Q_OBJECT:当在模板类中利用Q_OBJECT宏时,也必要包含.moc文件。
作用原理
Qt的元对象系统(Meta-Object System)必要为每个包含Q_OBJECT宏的类天生额外的代码,这些代码由Qt的元对象编译器(moc)天生。
- 当类定义在头文件中时,moc会天生一个名为moc_xxx.cpp的文件,这个文件会被自动编译和链接。
- 当类定义在cpp文件中时,moc同样会天生代码,但这些代码必要被包含到定义该类的cpp文件中,这就是为什么必要 #include "xxx.moc"。
示例
- // myfile.cpp
- #include <QObject>
- // 在cpp文件中定义的类
- class MyInternalClass : public QObject
- {
- Q_OBJECT
- public:
- MyInternalClass() {}
-
- signals:
- void someSignal();
-
- public slots:
- void someSlot() {
- emit someSignal();
- }
- };
- // 其他代码...
- // 必须在文件末尾包含生成的moc文件
- #include "myfile.moc"
复制代码 模板类示例
- // templateclass.cpp
- #include <QObject>
- template <typename T>
- class TemplateClass : public QObject
- {
- Q_OBJECT
- public:
- TemplateClass() {}
- T getValue() { return m_value; }
-
- signals:
- void valueChanged();
-
- public slots:
- void setValue(T value) {
- m_value = value;
- emit valueChanged();
- }
-
- private:
- T m_value;
- };
- // 模板实例化
- template class TemplateClass<int>;
- template class TemplateClass<QString>;
- // 包含生成的moc文件
- #include "templateclass.moc"
复制代码 注意事项
- 只有当类定义在cpp文件中且利用了Q_OBJECT宏时,才必要包含.moc文件
- .moc文件名应该与cpp文件名雷同
- 包含语句通常放在cpp文件的末尾
- 现代Qt项目利用CMake或qmake时,这些构建系统会自动处理moc的天生和包含
假如你的类定义在头文件中,则不必要如许做,因为Qt的构建系统会自动处理。
关于Qt中的.moc文件包含问题
moc天生的两种文件
Qt的元对象编译器(moc)会根据差别环境天生两种差别的文件:
- moc_xxx.cpp:当Q_OBJECT宏在头文件(.h)中利用时,moc会天生这种文件。这些文件会被自动编译成目标文件并链接到你的步伐中。
- xxx.moc:当Q_OBJECT宏在实现文件(.cpp)中利用时,moc会天生这种文件。这些文件必要被手动包含到对应的cpp文件中。
为什么必要包含xxx.moc
当你在cpp文件中定义一个包含Q_OBJECT宏的类时,moc会为这个类天生元对象代码,但这些代码被放在一个单独的xxx.moc文件中。由于这个类的定义只在cpp文件中可见(不在头文件中),所以天生的moc代码也必须包含在同一个cpp文件中才能访问这个类的定义。
这就是为什么你必要在cpp文件末尾添加#include "xxx.moc"的原因。
实际例子
- // mywidget.cpp
- #include "mywidget.h"
- // 正常的类实现...
- // 在cpp文件中定义的内部类
- class InternalHelper : public QObject
- {
- Q_OBJECT
- public:
- void doSomething();
-
- signals:
- void finished();
- };
- void InternalHelper::doSomething()
- {
- // 实现...
- emit finished();
- }
- // 必须包含生成的moc文件
- #include "mywidget.moc"
复制代码 在这个例子中,InternalHelper类只在mywidget.cpp文件中定义,所以moc天生的代码必须被包含在同一个文件中。
总结
- 当Q_OBJECT类定义在头文件中:moc天生moc_xxx.cpp,自动编译和链接
- 当Q_OBJECT类定义在cpp文件中:moc天生xxx.moc,必要手动包含到cpp文件中
这种区别是由于C++的编译模子和Qt元对象系统的工作方式决定的。通过这种方式,Qt确保了元对象代码可以或许精确访问类定义,无论类定义在那里。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |