Joe*_*ing 2 c++ inheritance qt
我最近收到了一份我正在处理的应用程序.
在我已经偶然发现继承问题后不久.
我有一个名为ModelBase的基类,它有一个纯虚方法,使它成为一个抽象类.该课程如下:
#ifndef MODELBASE_H
#define MODELBASE_H
#include <QMetaType>
#include <QString>
class ModelBase
{
public:
ModelBase();
virtual ~ModelBase();
long getId() const;
void setId(const long id);
virtual QString toString() const = 0;
private:
long m_id;
};
Q_DECLARE_METATYPE(ModelBase)
#endif // MODELBASE_H
Run Code Online (Sandbox Code Playgroud)
事实上它被声明为METATYPE可能需要记住读取其余代码.
我从这个基类派生了几个类.对于这个例子,我将使用两个给我带来最多问题的例子.
#ifndef PLATFORM_H
#define PLATFORM_H
#include <QDate>
#include "modelbase.h"
#include "game.h"
class Platform : ModelBase
{
public:
Platform();
~Platform();
QString toString() const;
QString getName();
QDate getPublishDate();
void setName(QString name);
void setPublishDate(QDate publishDate);
private:
QString m_name;
QDate m_publishDate;
QList<Game*> m_games;
};
#endif // PLATFORM_H
Run Code Online (Sandbox Code Playgroud)
如您所见,标头还包含父类ModelBase中的虚方法.
最后但并非最不重要的; 问题类:
#ifndef GAME_H
#define GAME_H
#include <QDate>
#include "modelbase.h"
class Platform;
class Publisher;
class Genre;
class Game : ModelBase
{
public:
Game();
~Game();
QString getTitle();
Publisher* getPublisher();
Genre* getGenre();
Platform* getPlatform();
QDate getPublishDate();
QString getLentTo();
void setTitle(QString title);
void setPublisher(Publisher &publisher);
void setGenre(Genre &genre);
void setPlatform(Platform &platform);
void setPublishDate(QDate date);
void setLentTo(QString lentTo);
QString toString() const;
private:
QString m_title;
Publisher *m_publisher;
Genre *m_genre;
Platform *m_platform;
QDate m_publishDate;
QString m_lentTo;
};
#endif // GAME_H
Run Code Online (Sandbox Code Playgroud)
既然代码到位了......
第一个问题来自循环依赖.
平台有很多游戏,游戏有一个平台.
我通过在games.h中声明平台并在platforms.h中包含games.h来解决这个问题
现在已经不在了,我编写了我的程序,得到了以下抱怨我真的不明白.
xxxxx\mingw47_32\include\QtCore\qmetatype.h:382: error: cannot allocate an object of abstract type 'ModelBase'
Run Code Online (Sandbox Code Playgroud)
确实公平.但我从来没有真正直接在类中定义ModelBase.只是源于它.
我在同一个日志中遇到的另一个错误是:
xxxx\mingw47_32\include\QtCore\qmetatype.h:-1: In instantiation of 'static void* QtMetaTypePrivate::QMetaTypeFunctionHelper<T, Accepted>::Create(const void*) [with T = ModelBase; bool Accepted = true]':
Run Code Online (Sandbox Code Playgroud)
我真的不知道这里发生了什么.
我尝试在games.h中根本不使用指针,但后来我得到了不同类型的编译器错误,我也不明白;
xxxx\game.h:38: error: field 'm_platform' has incomplete type
Run Code Online (Sandbox Code Playgroud)
我尝试过使用#include和forward声明,但它们都给了他们一些问题.还要注意,如果在games.h文件中,我用包括替换正向类声明(除了platform.h,这会带回循环依赖问题)所有问题都有不完整类型消失(除了m_platform,因为据我所知) ,我别无选择,只能向前宣布它)
我假设我不知道这个继承应该如何在这里工作.
我将ModelBase定义为元类型的原因是因为我想让ModelBase及其子元素从QVariant中包装/解包
发生最后一个错误,因为您的类中没有不完整类型的对象.编译器不知道要为此对象分配多少空间,因此类的内存布局将以某种方式未定义.相反,"指向不完整"的指针是可能的.
我不是Qt,但看起来你的Q_DECLARE_METATYPE()导致构造函数调用.根据定义,抽象类不可构造.
QMetaTypeFunctionHelper::Create :
static void *Create(const void *t)
{
if (t)
return new T(*static_cast<const T*>(t));
return new T();
}
Run Code Online (Sandbox Code Playgroud)
文档QMetaType类参考说:
Q_DECLARE_METATYPE(Type)只要它提供公共默认构造函数,公共复制构造函数和公共析构函数,该宏就会使QMetaType知道类型Type.需要在QVariant中使用Type类型作为自定义类型.
正如我所提到的:无法构造抽象类.
参见[Qt-interest] Q_DECLARE_METATYPE和抽象类:
星期一,8 de de de de 2011:12:36:16 Schimkowitsch Robert写道:
如何声明抽象基类的元类型?我在Q_DECLARE_METATYPE文档中没有看到任何禁止它的内容.
你没有.元类型需要是可默认构造的,可公开破坏的,可复制的和可分配的.
根本无法构造抽象类型.根据抽象的定义,您不希望复制它们,因为这样做会削减您拥有的专用对象.
您很可能希望将指针 的元类型注册到抽象类.
该Q_DECLARE_METATYPE抽象类确实是个问题.这不会"定义一个元类型的类",它使该类可用于Qt的MOC,例如在信号/槽参数中传递它,使其可用QVariant等等.但是,你不能在一个抽象的类上这样做 - 这没有道理.你确定你不是故意的:
Q_DECLARE_METATYPE(ModelBase*)
Run Code Online (Sandbox Code Playgroud)
关于其余警告 - 当编译器注意到错误时,大多数警告会尝试在源代码中查找其他问题.有时它运作良好,有时它只是给你虚假的警告.修复Q_DECLARE_METATYPE错误然后继续处理.
| 归档时间: |
|
| 查看次数: |
1473 次 |
| 最近记录: |