Qt继承和实例化问题
Qt inheritance and instantiation problems
我最近捡起了一个我之前做过的应用程序。
不久之后,我就遇到了继承的问题。
我有一个叫做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
声明为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
可以看到,头文件还包括来自父类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
现在代码已经就绪…
第一个问题是循环依赖。
一个平台有许多游戏,一个游戏有一个平台。
我通过在games.h中向前声明平台并在platforms.h中包含games.h来解决这个问题
现在解决了这个问题,我编译了我的程序,得到了以下抱怨,我真的不理解。
xxxxxmingw47_32includeQtCoreqmetatype.h:382: error: cannot allocate an object of abstract type 'ModelBase'
好吧…但是我从来没有真正直接在类中定义ModelBase。只从它推导。
我在同一日志中得到的另一个错误是:
xxxxmingw47_32includeQtCoreqmetatype.h:-1: In instantiation of 'static void* QtMetaTypePrivate::QMetaTypeFunctionHelper<T, Accepted>::Create(const void*) [with T = ModelBase; bool Accepted = true]':
我真的不知道这是怎么回事。
我试着不使用指针在所有的游戏。h,但后来我得到不同类型的编译器错误,我不理解;
xxxxgame.h:38: error: field 'm_platform' has incomplete type
我试过使用#include和forward声明,但它们都有共同的问题。还请注意,如果在games.h文件中,我用include替换了向前的类声明(除了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();
}
文档QMetaType Class Reference说:
Q_DECLARE_METATYPE (Type)只要提供一个公共默认构造函数、一个公共复制构造函数和一个公共析构函数,这个宏就使类型Type为QMetaType所知。需要在QVariant中使用type类型作为自定义类型。
如前所述:抽象类不能被构造。
参见[Qt-interest] Q_DECLARE_METATYPE和抽象类:
On Monday, 8 de August de 2011 12:36:16 Schimkowitsch Robert写道:
如何声明抽象基类的元类型?我见过Q_DECLARE_METATYPE-docs中没有任何禁止它的内容。
你不。元类型需要是默认可公开构造的可销毁、可复制、可赋值。
抽象类型根本不能被构造。根据抽象的定义同样,你也不想复制它们,因为那样做会剪切你有专门的对象。
您很可能想要注册指针的元类型到抽象类
抽象类上的Q_DECLARE_METATYPE
确实是一个问题。这不是"定义一个类的元类型",它使该类可用于Qt的MOC的目的,如传递它周围的信号/槽参数,使其在QVariant
等可用。但是,您不能在抽象类上这样做——这没有意义。你确定你不是这个意思吗?
Q_DECLARE_METATYPE(ModelBase*)
关于其余的警告——当编译器注意到一个错误时,它们中的大多数都试图在您的源代码中查找其他问题。有时它很有效,有时它只是给你虚假的警告。修复Q_DECLARE_METATYPE
错误,然后工作在其余的
Q_DECLARE_METATYPE
是当你想在QVariant (Qt高级联合)中使用特定类的对象或在信号和插槽连接中使用这些对象时使用的。
因此,将它用于虚类的对象是没有意义的,因为您可以首先构造虚类的对象。首先,Q_DECLARE_METATYPE(ModelBase*)
不能工作,因为参数需要是类型(解析非常基本)。其次,它不是必需的,因为您可以在Qt中使用任何指针而无需向系统声明它。
我刚刚遇到了一个类似的问题,在编写一些代码时,我后来想找到QVariant中存储的指针的类型。
通过使用QVariant::canConvert<ModelBase*>
,可以在稍后确定指针的类型,因此声明一个类型化指针而不是使用默认的void*
可能会很有用。
- 从C++实例化QML
- 错误 C2280 / 在 std::vector 中实例化对象时复制构造函数出现问题?
- 显式模板实例化问题
- 实例化函数模板的编译问题
- 模板函数实例化的可移植性问题
- 模板函数实例化 自定义数据类型的问题
- 字符串实例化问题
- 在 C++ 中实例化指向新对象的指针时出现问题
- 何时会隐式实例化导致问题
- Cygwin gcc编译器使用GAlib的模板实例化问题
- 复杂数据类型的模板实例化问题
- 类和函数模板实例化的Visual Studio dll导出问题
- c++中的工厂模式.实例化问题
- Qt继承和实例化问题
- c++中多态性基类和继承类实例化的问题
- 在实例化结构模板时出现问题
- 实例化模板化类的问题
- 实例化子类的多态性问题
- 对以下用户定义类片段中的模板实例化问题表示怀疑
- 继承——实例化问题