转载自:https://blog.csdn.net/weixin_39955229/article/details/81901603

原文标题:QObject多继承static_meta_object的编译问题

问题描述

继承一个类,再继承自QObject并添加Q_OBJECT的宏之后,编译不过。

class A{public:A(){};~A(){};private:int m_aval;};class DerivedObject : public A,public QObject
{Q_OBJECTpublic:DerivedObject();~DerivedObject();private:int m_dval;};

错误信息

错误 1 error C2039: “staticMetaObject”: 不是“A”的成员 c:\Users\chuan\documents\visual studio 2010\Projects\DerivedObject\DerivedObject\GeneratedFiles\Debug\moc_derivedobject.cpp 53 DerivedObject错误 2 error C2039: “qt_metacast”: 不是“A”的成员 c:\Users\chuan\documents\visual studio 2010\Projects\DerivedObject\DerivedObject\GeneratedFiles\Debug\moc_derivedobject.cpp 73 DerivedObject错误 3 error C2039: “qt_metacall”: 不是“A”的成员 c:\Users\chuan\documents\visual studio 2010\Projects\DerivedObject\DerivedObject\GeneratedFiles\Debug\moc_derivedobject.cpp 78 DerivedObject

问题分析

首先,我们尝试输出该类的内存布局,分析错误原因。

vs下右键属性->配置属性->C/C++->命令行,在下方其他选项中填入:

/d1 reportSingleClassLayout**DerivedObject**

加粗部分是具体的类名,表示输出哪个类的内存布局情况,可以自定义,我这里用的类名是 DerivedObject

设置完保存,直接编译,

    +---| +--- (base class QObject)0  | | {vfptr}4  | | ?$QScopedPointer@VQObjectData@@U?$QScopedPointerDeleter@VQObjectData@@@@ d_ptr| +---| +--- (base class A)8  | | m_aval| +---
12  | m_dval+---DerivedObject::$vftable@:| &DerivedObject_meta|  00  | &DerivedObject::metaObject1  | &DerivedObject::qt_metacast2  | &DerivedObject::qt_metacall3  | &DerivedObject::{dtor}4  | &QObject::event5  | &QObject::eventFilter6  | &QObject::timerEvent7  | &QObject::childEvent8  | &QObject::customEvent9  | &QObject::connectNotify
10  | &QObject::disconnectNotifyDerivedObject::metaObject this adjustor: 0
DerivedObject::qt_metacast this adjustor: 0
DerivedObject::qt_metacall this adjustor: 0
DerivedObject::{dtor} this adjustor: 0
DerivedObject::__delDtor this adjustor: 0
DerivedObject::__vecDelDtor this adjustor: 0

注意这里虚函数表的展开,有几个虚函数地址。但是我们并没有在DerivedObject中重写任何虚函数,那么这个虚函数表的布局为什么是这样的呢?

注意类定义的开始,加入了一个宏Q_OBJECT,进入定义发现:

#define Q_OBJECT \
public: \Q_OBJECT_CHECK \static const QMetaObject staticMetaObject; \Q_OBJECT_GETSTATICMETAOBJECT \virtual const QMetaObject *metaObject() const; \virtual void *qt_metacast(const char *); \QT_TR_FUNCTIONS \virtual int qt_metacall(QMetaObject::Call, int, void **); \
private: \Q_DECL_HIDDEN static const QMetaObjectExtraData staticMetaObjectExtraData; \Q_DECL_HIDDEN static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);

也就是说,只要包含了Q_OBJECT着个宏,它就会在编译的时候展开为一堆定义和重写的虚函数,然后在MOC的时候在CPP中加入定义。比如此时对应的moc_derivedobject.cpp里编译器自己加上的导致出错的地方:

const QMetaObject DerivedObject::staticMetaObject = {{ &A::staticMetaObject, qt_meta_stringdata_DerivedObject,qt_meta_data_DerivedObject, &staticMetaObjectExtraData }
};

注意第一个参数 &A::staticMetaObject,我们自己定义的类A是没有staticMetaObject着个成员的,这是QObject的宏展开之后才有的定义。此时如果把DerivedObject继承顺序更改一下:

class DerivedObject : public A,public QObject

其他部分保持不变,然后编译并输出:

const QMetaObject DerivedObject::staticMetaObject = {{ &QObject::staticMetaObject, qt_meta_stringdata_DerivedObject,qt_meta_data_DerivedObject, &staticMetaObjectExtraData }
};

编译通过: }。

输出内存布局A和QObject的只是顺序对换,因为DerivedObject继承自A和QObject的关系没有改变,即使顺序改变,Q_OBJECT宏只有一个static变量不占类的内存。

以上,继承QObject并加入Q_OBJECT宏的时候,QT环境下在编译的时候会以第一个继承的对象(模板?)来生成对应的moc文件,如果带有Q_OBJECT宏,必须把QObject放在第一个继承的位置。

error C2039: “staticMetaObject”: 不是“A”的成员 c:\Users\chuan\documents\visual studio 2010\Projects\Deriv相关推荐

  1. Qt error: C2039: “staticMetaObject”: 不是“QXXX”的成员

    error: C2039: "staticMetaObject": 不是"QgsAnnotationMarkerItem"的成员 #include <QO ...

  2. error: C2039: “staticMetaObject”: 不是“QGraphicsItem”的成员

    当使用Qt的图形视图框架时,自定义图形类时,一般这样写 class myItem:public QGraphicsItem { public:myItem();void paint(QPainter ...

  3. Visual studio 2010出现“error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏”解决方式...

    本来自己的电脑上装了VS2010,因为开发Cocos2d-x 3.x,所以就在自己的机器上装了一个VS2012. 但是.这不装不要紧,debug一下自己原来的程序,结果出现了"error L ...

  4. 在visual studio 2010+中调用ffmpeg编译时 报错error LNK xxxx: 模块对于 SAFESEH 映像是不安全的。...

    解决该错误的方法: 1.右键单击该项目选择"属性". 2.在属性页中选择:配置选项->链接器->命令行. 3. 在命令行的"其他选项"中输入/SAF ...

  5. BUG: Setup Was Unable to Create a DCOM User Account Error Message in Visual Studio 6.0

    今天在安装VS 6.0时,遇见这个问题:Setup was unable to create a DCOM user account in order to register <path> ...

  6. error C2039: “type”: 不是“cv::DataTypeT”的成员 解决办法

    编译opencv4.0.x版本的程序时,由于个人疏忽致使opencv 函数参数顺序调用错误,但是编译时没有提示该语句参数顺序错误,提示以下错误: g:\library\opencv-master\bu ...

  7. error C2039: “SetDefaultDllDirectories”: 不是“`global namespace’”的成员

    error C2039: "SetDefaultDllDirectories": 不是"`global namespace'"的成员 使用2013编译程序的时候 ...

  8. error C2039: IsOutRange

    error C2039: "IsOutRange 解决MNN中nmake编译出现IsOutRange is not a member of flatbuffers 参考了https://bl ...

  9. error C2039: ‘tr1‘: is not a member of ‘std‘

    最近在VS2019的工程中集成gtest,发现报错如下: error C2039: 'tr1': is not a member of 'std' error C3083: 'tr1': the sy ...

最新文章

  1. 开发日记-20190806 关键词 读书笔记《Linux 系统管理技术手册(第二版)》DAY 20
  2. easyUI的引用方式
  3. python对windows进行操作_【转】python 操作windows下的目录
  4. Apache 与 Nginx
  5. python decorator. decorator_Python装饰器(decorator)
  6. js中常用的数组和字符串方法
  7. oracle移动表所在的表空间,ORACLE移动表空间(原)
  8. Payroll Calculation的Process Rule
  9. NO4 findmv--特殊符号..和.
  10. 2018-05-16树莓派如何开启UART串口
  11. MVCC常问面试题(面试重点)
  12. Go语言入门之指针的使用
  13. java三角函数计算器_java实现多功能科学计算器(包括进制转换,三角函数,四则运算等)...
  14. 省市县乡四级联动java代码,jQuery省市区街道四级联动代码
  15. 教室录播系统方案_录播教室技术解决方案
  16. YY一下淘宝商品模型
  17. 大厂面试快问快答,10分钟搞定MySQL夺命20问,你都能接住吗?
  18. 英语3500词(二) your dream lover主题 (2022.1.14)
  19. with revoked permission android.permission.CAMERA
  20. 有关STM32F103C8T6的超频

热门文章

  1. Handsome主题添加Sticker-Heo表情包
  2. 光伏发电上网电量无线传输/4G能源数据集中器/能源数据采集终端
  3. layui弹出层的表单验证
  4. iOS AFN监控联网状态~demo
  5. 泛世纪上大量最新的录制课程啊。欢迎来下载
  6. 牛根生经典语录-2011
  7. Chisel 教程翻译 之 第一章:概述介绍《Digital Design with Chisel》
  8. GNS3 cloud 连接错误_条码打印软件连接SQLServer出现TCP连接失败解决办法
  9. android反编译后有中文乱码,android反编译查看源码,apk解压后XML乱码解决
  10. 循环for与while的区别