本文是一篇关于类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. Java遍历解析URL类型字符串中参数

    public static void main(String[] args) { String str="&emailCheckURL=447&useremail=vip@c ...

  2. jQuery库(noConflict)冲突解决机制

    很多JSFramework库选择使用$符号作为一个函数或变量名,而在实际的项目开发,模板语言,则有可能"$"符号是模板语言keyword.例如Veclocity模板语言,$它是ke ...

  3. 快速构建Windows 8风格应用6-GridView数据控件

    原文:快速构建Windows 8风格应用6-GridView数据控件 本篇博文主要介绍什么是GridView数据控件.如何构建常用的GridView数据呈现样式. 什么是GridView数据控件? G ...

  4. Web Service单元测试工具实例介绍之SoapUI

    原文  Web Service单元测试工具实例介绍之SoapUI SoapUI是当前比较简单实用的开源Web Service测试工具,提供桌面应用程序和IDE插件程序两种使用方式.能够快速构建项目和组 ...

  5. 通过 C# 代码操作 Google 日历

    原文:通过 C# 代码操作 Google 日历 本文主题 借助 Google .NET APIs Client Library,通过 C# 代码在 Google 日历中创建会议邀请. 本文背景 最近, ...

  6. 查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究

    原文:查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究 查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究 -理解性能疑点 1      引言 内容来自http://www.so ...

  7. 所有MVP文章

    http://msdn.microsoft.com/zh-cn/dd346590.aspx

  8. Mysql 嵌套游标添以及任意位置声明变量的方法

    在写存储过程的时候,会遇到某个游标的筛选条件来自于 先前语句运行的结果,比较常见的方式是 再写一个存储过程,通过调用来完成 动态参数的配置, 或者使用 动态sql的功能,而这两种方式都不能很好的解决这 ...

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

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