类classthe Meta-Object Compiler (moc)
本文是一篇关于类class的帖子
the Meta-Object Compiler (moc)
元对象编译器是处理Qt的C++扩展的程序。
moc工具读取C++头文件,如果它找到一个或者多个类声明包含Q_OBJECT宏。它生为那些类成一个包含元对象代码的C++源文件。元对象代码是信号与槽机制,运行时信息和动态属性系统所必须的。
moc生成的C++源文件在类的实现过程当中必须停止编译和连接。
如果你用qmake创立makefiles,包含的创立规则在须要的时候调用moc,所以你不用直接使用moc。
Usage
moc典型的用法,输入文件包含的类声明:
class MyClass : publicQObject
{
Q_OBJECT
public:
MyClass(QObject*parent =);
~MyClass();
signals:
void mySignal();
publicslots:
void mySlot();
};
除了以上显示的信号与槽机制外,moc实现对象属性如下例子。Q_PROPERTY()宏声明白一个对象属性, Q_ENUMS()在类中声明白一个枚举类型,可以用在属性系统中。
在下面的例子,我们声明白一个枚举属性,一个获取属性的方法priority() 和设置属性的方法setPriority().。
- class MyClass : public QObject
- {
- Q_OBJECT
- Q_PROPERTY(Priority priority READ priority WRITE setPriority)
- Q_ENUMS(Priority)
- public:
- enum Priority { High, Low, VeryHigh, VeryLow };
- MyClass(QObject *parent =);
- ~MyClass();
- void setPriority(Priority priority) { m_priority = priority; }
- Priority priority() const { return m_priority; }
- private:
- Priority m_priority;
- };
Q_FLAGS() 宏声明一个可以用作标记的枚举值。另外一个宏 Q_CLASSINFO(), 允许你给类的元对象添加额外的name/value对信息。
- class MyClass : public QObject
- {
- Q_OBJECT
- Q_CLASSINFO("Author","Oscar Peterson")
- Q_CLASSINFO("Status","Active")
- public:
- MyClass(QObject *parent =);
- ~MyClass();
- };
moc生成的文件必须和程序中的其他C++源文件一样停止编译和链接;否则,在在生成的链接阶段将失败。如果你使用qmake,这将会自动实现。当qmake允许起来,它剖析工程的头文件和生成创立规则认为那些包含 Q_OBJECT宏的文件停止调用moc。
如果类在myclass.h中声明,moc生成 的文件为moc_myclass.cpp。这个文件一样停止编译,在windows上生成的目标文件moc_myclass.obj。这个目标文件在程序生成过程都须要停止连接的。
Writing Make Rules for Invoking moc
为了简略的测试程序,提议自动运行moc。通过添加规则到程序的makefile,可以在须要的时候很好的运行moc和处理moc的生成文件。
我们提议使用qmake 的makefile生成工具创立makefile。这个工具生成moc须要的全部操作的makefile。
如果你想创立自己的makefile,这里有一些如何包含moc操作的提示。
对于头文件中 Q_OBJECT宏声明,如果你只用GNU make这里有一个很有效的makefile规则:
- moc_%.cpp: %.h
- moc $(DEFINES) $(INCPATH) $<-o $@
如果你想写的更灵活,你可以用如下的独自的规则格式:
- moc_foo.cpp: foo.h
- moc $(DEFINES) $(INCPATH) $<-o $@
你必须记得添加moc_foo.cpp到你的SOURCES 变量和moc_foo.o 或moc_foo.obj到你的OBJECTS 变量。
全部的例子都假设$(DEFINES) 和 $(INCPATH) 展开到传递到C++编译器的define和include路径选项。这些都是moc在停止源文件的预处理时须要的。
我们爱好把源文件命名为.cpp。其实也可以用其他扩展,如.c,.cc,.CC,.cxx和.c++。
对于.cpp文件中的r Q_OBJECT宏声明,我们提议makefile规则如下:
- foo.o: foo.moc
- foo.moc: foo.cpp
- moc $(DEFINES) $(INCPATH) -i $<-o $@
这保障了在编译foo.cpp之前允许moc,你可以把:
- #include "foo.moc"
放在foo.cpp的末尾。全部类声明都已完整可知的地方。
Command-Line Options
以下是moc支持命令行选项:
曾经辉煌过,曾经凋零过,这可是你至死不渝的生活吗?我亲爱的母亲—大自然。多少次,我伏在地上,去聆听你沉重的脉搏声;多少次,我伫立在山前,去感受那松涛千年的浩瀚。你的豪壮,足以让中华民族腾飞;你的无私,谱写了一曲曲感人至深的千古壮曲。
Option |
Description |
-o<file> |
Write output to <file> rather than to standard output. |
-f[<file>] |
Force the generation of an #include statement in the output. This is the default for header files whose extension starts with H or h. This option is useful if you have header files that do not follow the standard naming conventions. The <file> part is optional. |
-i |
Do not generate an #include statement in the output. This may be used to run the moc on on a C++ file containing one or more class declarations. You should then #include the meta-object code in the .cpp file. |
-nw |
Do not generate any warnings. (Not recommended.) |
-p<path> |
Makes the moc prepend <path>/ to the file name in the generated #include statement. |
-I<dir> |
Add dir to the include path for header files. |
-E |
Preprocess only; do not generate meta-object code. |
-D<macro>[=<def>] |
Define macro, with optional definition. |
-U<macro> |
Undefine macro. |
@<file> |
Read additional command-line options from <file>. Each line of the file is treated as a single option. Empty lines are ignored. Note that this option is not supported within the options file itself (i.e. an options file can't "include" another file). |
-h |
Display the usage and the list of options. |
-v |
Display moc's version number. |
-Fdir |
Mac OS X. Add the framework directory dir to the head of the list of directories to be searched for header files. These directories are interleaved with those specified by -I options and are scanned in a left-to-right order (see the manpage for gcc). Normally, use -F /Library/Frameworks/ |
你可以显示的告知moc不要剖析头文件中的某些部分。moc定义了预处理宏 Q_MOC_RUN. 。
以下代码将被moc忽略。
- #ifndef Q_MOC_RUN
- ...
- #endif
Diagnostics
在 Q_OBJECT 类声明中,moc会给出一些危险或者合法的创立的警告。
如果在程序生成的最后阶段产生连接错误,说YourClass::className() 没有定义或YourClass缺乏虚函数表vtable。一定是涌现了某些错误。最可能的是,你忘记编译或 #include包含了moc生成的C++源文件,或者在连接命令忘记包含目标文件。如果你用qmake,试着重新运行更新makefile,这就行了。
Limitations
moc不能处理全部的C++。最主要的问题是模板类不能用信号或槽。例如:
主要的是,以下的结构都是合法的。他们都选择了我们认为是更好的,所以去掉这些限制对我们来说并不是优先选择。
MultipleInheritance Requires QObject to Be First
如果使用多继承,moc假定第一个被继承的类是 QObject.的子类。确保只有第一个被继承的类是QObject.。
不支持对QObject的虚拟继承。
FunctionPointers Cannot Be Signal or Slot Parameters
在大部分情况,你可以斟酌使用函数指针作为信号或槽的参数,我们觉得继承是一个号的替换选择。如下例子有语法错误:
- class SomeClass : public QObject
- {
- Q_OBJECT
- publicslots:
- void apply(void (*apply)(List *, void *), char *); // WRONG
- };
我们可以停止如下变通:
- typedef void (*ApplyFunction)(List *, void *);
- class SomeClass : public QObject
- {
- Q_OBJECT
- publicslots:
- void apply(ApplyFunction, char *);
- };
最好还是用继承或虚函数替换函数指针。
Enumsand Typedefs Must Be Fully Qualified for Signal and Slot Parameters
当检查参数的签名时, QObject::connect() 逐字地的停止比拟数据类型。因此, Alignment和 Qt::Alignment 被当成不同的类型。为了解决这个问题,当声明信号和槽,或者建立connection时,确保取得数据类型的完整资历。
- class MyClass : public QObject
- {
- Q_OBJECT
- enum Error {
- ConnectionRefused,
- RemoteHostClosed,
- UnknownError
- };
- signals:
- void stateChanged(MyClass::Error error);
- };
NestedClasses Cannot Have Signals or Slots
这是个结构欠好的例子:
- class A
- {
- public:
- class B
- {
- Q_OBJECT
- publicslots: // WRONG
- void b();
- };
- };
Signal/Slotreturn types cannot be references
信号和槽可以有返回类型,但是信号或槽返回引用会被当成返回void。
Only Signals and Slots May Appear in the signals and slots Sections of aClass
moc会埋怨,如果你试图将信号和槽意外的结构放在信号和槽段。
文章结束给大家分享下程序员的一些笑话语录: 程序员的愿望
有一天一个程序员见到了上帝.上帝: 小伙子,我可以满足你一个愿望.程序员: 我希望中国国家队能再次打进世界杯.
上帝: 这个啊!这个不好办啊,你还说下一个吧!
程序员: 那好!我的下一个愿望是每天都能休息6个小时以上.
上帝: 还是让中国国家打进世界杯.
---------------------------------
原创文章 By
类和class
---------------------------------
类classthe Meta-Object Compiler (moc)的更多相关文章
- Qt Meta Object System-元对象系统
研一的时候开始使用Qt,感觉用Qt开发图形界面比MFC的一套框架来方便的多.后来由于项目的需要,也没有再接触Qt了.现在要重新拾起来,于是要从基础学起. Now,开始学习Qt事件处理机制. 元对象系统 ...
- 6、Qt Meta Object system 学习
原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...
- Qt Meta Object system 学习
原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...
- the Meta-Object Compiler (moc)
the Meta-Object Compiler (moc) 元对象编译器是处理Qt的C++扩展的程序. moc工具读取C++头文件,如果它找到一个或者多个类声明包含Q_OBJECT宏.它生为那些类成 ...
- python---Django中模型类中Meta元对象了解
Django中模型类中Meta元对象了解 1.使用python manage.py shell 进入编辑命令行模式,可以直接进入项目(为我们配置好了环境) python manage.py shell ...
- 13_Python的面向对象编程-类class,对象object,实例instance
1.面向对象概述 1.类是用来描述对象的工具,把拥有相同属性和行为的对象分为一组 2.对象是由类实例化出来的一个具体的对象 属性: 对象拥有的名词,用变量表示 ...
- 把一个类(或者Object)转换成字典
直接上代码:把一个类转换成object,然后在转换成字典 internal static IDictionary<string, string> GetDictionary(this ob ...
- python定义类()中写object和不写的区别
这里需要说明一下: python3中,类定义默认继承object,所以写不写没有区别 但在python2中,并不是这样 所以此内容是针对python2的,当然python3默认继承,不代表我们就傻乎乎 ...
- Python中新式类 经典类的区别(即类是否继承object)
首先什么是新式类 经典类呢: #新式类是指继承object的类 class A(obect): ........... #经典类是指没有继承object的类 class A: ........... ...
随机推荐
- dd命令简单易用,例如
dd命令简单易用,例如 bs单位,count为写入的范围区间,例如以下举例: 例:使用dd清除vote disk和ocr(裸设备) $dd if=/dev/zero of=/dev/rrac_ocr ...
- windows下使用pthread
有的时候需要使用多线程来测试代码啥的,在Linux下有pthread,在windows也有. 我这儿是使用MingW作为编译工具,具体如何下载MingW自行在网上搜索. 而pthread是在这里下载的 ...
- Erlang常用代码段
十六进制字符串转为二进制 hex_to_bin(Bin) -> hex2bin(Bin). hex2bin(Bin) when is_binary(Bin) -> hex2bin(bina ...
- 快速构建Windows 8风格应用16-SettingContract原理及构建
原文:快速构建Windows 8风格应用16-SettingContract原理及构建 本篇博文主要介绍Setting Contract概述.Setting Contract实现基本原理.如何构建Se ...
- [译]Java 设计模式之外观
(文章翻译自Java Design Pattern: Facade) 外观设计模式隐藏了任务的复杂性而只是提供了一个简单的接口.一个非常好的例子就是计算机的启动.当一个计算机启动的时候,它涉及CUP. ...
- fullCalendar:中文API
1.与google日历连接,别忘记加入<script type='text/javascript' src='js/gcal.js'/> events: $.fullCalendar.gc ...
- SDUTOJ 2054 双向链表
#include<iostream> #include<stdlib.h> using namespace std; typedef int ElemType; typedef ...
- TRIGGER的使用(修改SP自动触发)
CREATE TRIGGER [trg_save_change_SP] ON DATABASE FOR CREATE_PROCEDURE, ALTER_PROCEDURE,DROP_PROCEDURE ...
- windows2008 配置安装FTP服务器
windows2008 配置安装FTP服务器 今天在服务器上开了IIS7,但是要求把一个附件文件夹拷贝到根目录下面,这个附件文件夹有2G多大小,直接用远程桌面映射,一直都拷贝不成功,而且本地缓存越来越 ...
- ASP.NET MVC IOC之Unity攻略
ASP.NET MVC IOC之Unity攻略 一.你知道IOC与DI吗? 1.IOC(Inversion of Control )——控制反转 即依赖对象不在被依赖模块的类中直接通过new来获取 先 ...