本文是一篇关于类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++。最主要的问题是模板类不能用信号或槽。例如:

class SomeTemplate<int> : public QFrame
{
    Q_OBJECT
    ...
 
signals:
    void mySignal(int);
};

主要的是,以下的结构都是合法的。他们都选择了我们认为是更好的,所以去掉这些限制对我们来说并不是优先选择。

MultipleInheritance Requires QObject to Be First

如果使用多继承,moc假定第一个被继承的类是 QObject.的子类。确保只有第一个被继承的类是QObject.。

// correct
class SomeClass : public QObject,public OtherClass
{
    ...
};

不支持对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)的更多相关文章

  1. Qt Meta Object System-元对象系统

    研一的时候开始使用Qt,感觉用Qt开发图形界面比MFC的一套框架来方便的多.后来由于项目的需要,也没有再接触Qt了.现在要重新拾起来,于是要从基础学起. Now,开始学习Qt事件处理机制. 元对象系统 ...

  2. 6、Qt Meta Object system 学习

    原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...

  3. Qt Meta Object system 学习

    原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...

  4. the Meta-Object Compiler (moc)

    the Meta-Object Compiler (moc) 元对象编译器是处理Qt的C++扩展的程序. moc工具读取C++头文件,如果它找到一个或者多个类声明包含Q_OBJECT宏.它生为那些类成 ...

  5. python---Django中模型类中Meta元对象了解

    Django中模型类中Meta元对象了解 1.使用python manage.py shell 进入编辑命令行模式,可以直接进入项目(为我们配置好了环境) python manage.py shell ...

  6. 13_Python的面向对象编程-类class,对象object,实例instance

    1.面向对象概述 1.类是用来描述对象的工具,把拥有相同属性和行为的对象分为一组     2.对象是由类实例化出来的一个具体的对象         属性: 对象拥有的名词,用变量表示         ...

  7. 把一个类(或者Object)转换成字典

    直接上代码:把一个类转换成object,然后在转换成字典 internal static IDictionary<string, string> GetDictionary(this ob ...

  8. python定义类()中写object和不写的区别

    这里需要说明一下: python3中,类定义默认继承object,所以写不写没有区别 但在python2中,并不是这样 所以此内容是针对python2的,当然python3默认继承,不代表我们就傻乎乎 ...

  9. Python中新式类 经典类的区别(即类是否继承object)

    首先什么是新式类 经典类呢: #新式类是指继承object的类 class A(obect): ........... #经典类是指没有继承object的类 class A: ........... ...

随机推荐

  1. Virtualbox之Ubuntu虚拟机网络访问设置

    在本机(Win7)中 利用VirtualBox安装了一个Ubuntu虚拟机,由于使用桥接,所以本机和虚拟机处于同一个网络局域网下,,主机能访问虚拟机.可是在Ubuntu更新软件的时候才发现不能联网.首 ...

  2. CSS学习笔记:文本换行显示(word-wrap)

    在CSS3中新定义了文本换行属性,word-wrap: nomal属性值表示控制连续文本换行. break-word属性值表示内容将在边界内换行.如果需要,词内换行(word-break)也会发生. ...

  3. MySQL之数据库结构优化

    1.选择合适的数据类型 一.选择能够存下数据类型最小的数据类型 二.可以使用简单的数据类型.int  要比varchar在MySQL处理上简单 三.尽可能的使用not null  定义字段 四.尽量少 ...

  4. SSIS Package to Call Web Service

    原文 SSIS Package to Call Web Service SSIS Package to Call Web Service. You can Call WebService from S ...

  5. .NET MVC4 实训记录之二(扩展WebSecurity模型下的UserProfile表)

    使用VS2013创建MVC4项目后,自动生成的代码中默认使用WebSecurity模型创建用户管理,生成以下数据库:

  6. sql汉字转拼音

    /*创建取拼音首字母函数*/ create function [dbo].[fn_ChineseToSpell](@strChinese varchar(500)='') returns varcha ...

  7. 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 ...

  8. Effective C++(18) 让接口更容易被正确使用,不易被误用

    问题聚焦:     从这个条款开始,我们把注意力转移到软件设计和声明上来,具体的说就是,C++接口的设计和声明.     所谓软件设计,就是以一般习惯的构想开始,演变成细节的实现,最终开发针对性的特殊 ...

  9. iOS基础 - 通知中心(NSNotificationCenter)

    通知中心(NSNotificationCenter) 每一个应用程序都有一个通知中心(NSNotificationCenter)实例,专门负责协助不同对象之间的消息通信 任何一个对象都可以向通知中心发 ...

  10. [转]The Best Plugins for Sublime Text

    Source: http://ipestov.com/the-best-plugins-for-sublime-text/ Good day, everyone! I tried to collect ...