类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: ........... ...
随机推荐
- Java遍历解析URL类型字符串中参数
public static void main(String[] args) { String str="&emailCheckURL=447&useremail=vip@c ...
- jQuery库(noConflict)冲突解决机制
很多JSFramework库选择使用$符号作为一个函数或变量名,而在实际的项目开发,模板语言,则有可能"$"符号是模板语言keyword.例如Veclocity模板语言,$它是ke ...
- 快速构建Windows 8风格应用6-GridView数据控件
原文:快速构建Windows 8风格应用6-GridView数据控件 本篇博文主要介绍什么是GridView数据控件.如何构建常用的GridView数据呈现样式. 什么是GridView数据控件? G ...
- Web Service单元测试工具实例介绍之SoapUI
原文 Web Service单元测试工具实例介绍之SoapUI SoapUI是当前比较简单实用的开源Web Service测试工具,提供桌面应用程序和IDE插件程序两种使用方式.能够快速构建项目和组 ...
- 通过 C# 代码操作 Google 日历
原文:通过 C# 代码操作 Google 日历 本文主题 借助 Google .NET APIs Client Library,通过 C# 代码在 Google 日历中创建会议邀请. 本文背景 最近, ...
- 查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究
原文:查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究 查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究 -理解性能疑点 1 引言 内容来自http://www.so ...
- 所有MVP文章
http://msdn.microsoft.com/zh-cn/dd346590.aspx
- Mysql 嵌套游标添以及任意位置声明变量的方法
在写存储过程的时候,会遇到某个游标的筛选条件来自于 先前语句运行的结果,比较常见的方式是 再写一个存储过程,通过调用来完成 动态参数的配置, 或者使用 动态sql的功能,而这两种方式都不能很好的解决这 ...
- Visual Studio 2013 Use HTTPS (SSL) On Web Application Projects
公司调试HTTPS接口会用到,原文:http://www.codeproject.com/Tips/766918/Visual-Studio-Use-HTTPS-SSL-On-Web-Applicat ...
- Asp.net MVC4.0(net4.5) 部署到window server 2003上的解决方案
Asp.net MVC4.0(net4.5) 部署到window server 2003上的解决方案 最近做了一个Web项目,也没多想就用了Asp.net MVC4.0 ,MVC4.0默认的目标fra ...