无意中发现在Qt的文档里有一篇关于moc工具的limitation的文章,里头的东西值得学习一下。

Qt一个链接的错误, 程序结构很简单, 就是designer设计主界面,在代码里用多重继承方式使用, 奇怪的错误信息如下:

moc_mainwin.cpp:39: error: ‘staticMetaObject’ is not a member of ‘Ui::MainWindow’
moc_mainwin.cpp: In member function ‘virtual void* MainWin::qt_metacast(const char)’: moc_mainwin.cpp:56: error: ‘qt_metacast’ is not a member of ‘MainWin::qt_metacast(const char)::QMocSuperClass’
moc_mainwin.cpp: In member function ‘virtual int MainWin::qt_metacall(QMetaObject::Call, int, void)’: moc_mainwin.cpp:62: error: ‘qt_metacall’ is not a member of ‘MainWin::qt_metacall(QMetaObject::Call, int, void)::QMocSuperClass’
make: *** [moc_mainwin.o] Error 1

Qt自动生成的moc文件竟然也会编译出错?这可真有点匪夷所思。把工程拿过来从头看到尾也没有看出任何错误可能会导致这个链接错误。 N长时间后,一个编译阶段报出的warning引起了我的注意, 大意是说多重继承不能从两个QObject类继承, 这就怪了,它怎么会把我的UI类也当成是从QObject派生的呢? 有了这个提示,尝试着修改多重继承的那行代码:

class MainWin: public Ui::MainWindow, public QWidget

改为

class MainWin: public QWidget, public Ui::MainWindow

结果你猜怎么着?奇迹发生了……呵呵,编译成功!原来竟然是继承的顺序造成的问题。 莫非这是Qt的bug?

给trolltech support发bug report得到了这样的回答:

This is actually a known limitation which has been documented for some time, when using multiple inheritance you have to specify the QObject based class first and then the other class. Its mentioned in the documentation at:
http://doc.trolltech.com/4.5/moc.html
under the limitations section.

原来如彼! 看来咱的道行还不够,这么重要的文档竟然从来都不知道它的存在。
仔细阅读一下居然发现还有不少Qt中和moc相关的编程限制需要我们注意, 各位看官也来受受再教育吧:

moc的功能数一数

  1. 处理Q_OBJECT宏和signals/slots关键字,生成信号和槽的底层代码
  2. 处理Q_PROPERTY()和Q_ENUM()生成property系统代码
  3. 处理Q_FLAGS()和Q_CLASSINFO()生成额外的类meta信息
  4. 不需要moc处理的代码可以用预定义的宏括起来,如下:

    #ifndef Q_MOC_RUN

    #endif

moc的限制数一数(太多了,眼花缭乱)

  1. 模板类不能使用信号/槽机制
  2. moc不扩展宏,所以信号和槽的定义不能使用宏, 包括connect的时候也不能用宏做信号和槽的名字以及参数
  3. 从多个类派生时,QObject派生类必须放在第一个, 因为moc是这么认为的…(比较流氓) 这也是我们前面的例子触犯的天条
  4. 函数指针不能作为信号或槽的参数, 因为其格式比较复杂,moc处理不了。 但可以用typedef把它定义成简单的形式再使用。(这招可真够绝的)
  5. 用枚举类型或typedef的类型做信号和槽的参数时,必须fully qualified。 这个词中文不知道怎么翻译才合适,简单的说就是, 如果是在类里定义的, 必须把类的路径或者命名空间的路径都加上, 防止出现混淆。 如Qt::Alignment之类的,前面的Qt就是Alignment的qualifier, 必须加上,而且有几级加几级。
  6. 信号和槽不能返回引用类型
  7. signals和slots关键字区域只能放置信号和槽的定义,不能放其它的如变量定义等
  8. 呵呵,这些限制条款感觉颇像不平等条约, 是不是让你大开眼界了呢? 其实这些限制有一部分应该当作bug来论处, 只是对Qt编程影响不算太大,可暂时忽略,所以被归入优先级很低的问题处理了(意思就是可能永远都不改了)。

转载于:https://www.cnblogs.com/sunpan822/p/8677474.html

(转载)Qt中MOC的一些限制相关推荐

  1. Qt中moc问题(qt moc 处理 cpp)

    Qt编译常见的错误: 编译报错: 1>Linking... 1>cmmwindow.obj : error LNK2001: unresolved external symbol &quo ...

  2. Qt中关于undefined reference to `vtable for故障总结

    在Qt中,undefined reference to 'vtable for 通常出现在打开了宏 Q_OBJECT的程式当中.我遇到的情况是: 将类体及类体实现直接写到main.cpp里,没有包含 ...

  3. QT中 :-1: error: Failed to resolve include /moc_predefs.h“ for moc file

    QT中 在构建时,出现如下问题:

  4. [转载]qt信号signal和槽slot机制

    好东西! 原文地址:qt信号signal和槽slot机制作者:fox1987 信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工具以及在实际使用过程中应注 ...

  5. QT中PRO文件写法的详细介绍,很有用,很重要!

    在QT中,有一个工具qmake可以生成一个makefile文件,它是由.pro文件生成而来的,.pro文件的写法如下: 1. 注释 从"#"开始,到这一行结束. 2.模板变量告诉q ...

  6. Qt中的问题和方法总结

    1. QString与String的转换 //1.QString转换String QString qstr = "hello"; string str = qstr.toStdSt ...

  7. Qt中的 Size Hints 和 Size Policies

    sizeHint 这个属性所保存的 QSize 类型的值是一个被推荐给窗口或其它组件(为了方便下面统称为widget)的尺寸,也就是说一个 widget 该有多大,它的一个参考来源就是这个 sizeH ...

  8. qt中设置窗口左上角的图标

    前面一节已经详细的讲解了怎么添加图片到qt的图片资源文件中,这里就不赘述了,不太了解的可以看看博主的这篇随笔:qt中建立图片资源管理文件 this->setWindowIcon(QIcon(&q ...

  9. QT中树控件QTreeView开发实例

    转自:http://mobile.51cto.com/symbian-268700.htm 本文讲解了QT中树控件QTreeView开发实例,对于QTreeView没有过多的讲解,那么不说废话了,看代 ...

最新文章

  1. ogg mysql的原理_OGG基础原理了解
  2. Idea中一个服务按多个端口同时启动
  3. Redis设计与实现之SDS和链表
  4. SonarQube开机自启动
  5. atomic、锁、多线程
  6. mysql 函数无法访问_mysql 中出现:不能打开到主机的连接,在端口3306: 连接失败...
  7. 【电力负荷预测】基于matlab粒子群算法优化支持向量机预测电力负荷【含Matlab源码 1225期】
  8. tlwn823n无线网卡驱动 linux,centos 6.5安装 TP-link TL-wn823n驱动
  9. 中科易安:公安对接流动人口管理智能锁需要联网吗?
  10. Android 混淆规则
  11. Aspose.Cells 使用UnMerge()取消合并单元格(取消合并单行,取消合并单列,取消多行多列)
  12. 拼多多商家有效评价是什么意思?拼多多的评价被屏蔽的原因有哪些呢?
  13. 移动终端基础数据管理系统
  14. 2014微软校园招聘笔试试题(英文)
  15. C语言链表实现商品库存管理系统
  16. 分享一个神器,我们前端再也不怕UI设计图不标注了
  17. 谷歌浏览器 Google Chrome v74.0.3729.131 正式版
  18. mesos安装--软件源安装
  19. apache common base64编码
  20. CSAPP lab2 经典的bomblab二次学习

热门文章

  1. vue 直接访问静态图片_vue中本地静态图片路径写法
  2. php cgi进程很多win2008,php cgi.exe 太多 在 windowserver2008 apache 这个怎么样限制下?...
  3. python超神之路:Python3 列表list合并的4种方法
  4. 转:org.apache.maven.archiver.MavenArchiver.getManifest错误
  5. cmd窗口快速定位到具体文件夹方法
  6. windows下解决mysql5中文乱码的问题
  7. 自动化测试用例设计原则
  8. 动态代理3之代理工厂实现
  9. Python3 From Zero——{最初的意识:007~函数}
  10. C# 委托:把方法组合到一个数组中使用