しばらく前に取り組んでいたアプリケーションを最近手に入れました。
継承に関する問題に出くわした直後です。
純粋仮想メソッドを持つ 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 として宣言されているという事実は、残りのコードを読む上で心に留めておくべきことです。
この基本クラスからいくつかのクラスを派生させました。この例では、ほとんどの問題を引き起こす 2 つを使用します。
#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
これでコードが配置されました...
最初の問題は、循環依存関係にあります。
プラットフォームには多くのゲームがあり、ゲームには 1 つのプラットフォームがあります。
games.h でプラットフォームを宣言し、platforms.h に games.h を含めることで解決しました。
それが邪魔にならないようになったので、私は自分のプログラムをコンパイルし、本当に理解できない次の苦情を受けました。
xxxxx\mingw47_32\include\QtCore\qmetatype.h:382: error: cannot allocate an object of abstract type 'ModelBase'
わかりました..しかし、クラスで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]':
ここで何が起こっているのか本当にわかりません。
games.h でポインターをまったく使用しないようにしましたが、理解できないさまざまな種類のコンパイラ エラーが発生します。
xxxx\game.h:38: error: field 'm_platform' has incomplete type
#include 宣言と forward 宣言の両方を使用してみましたが、いずれも問題を共有しています。また、games.h ファイルで前方クラス宣言をインクルード (循環依存の問題を引き起こす platform.h を除く) に置き換えると、不完全な型のすべての問題が消えることに注意してください (私が知る限り、m_platform を除く)。 、私はそれを前方宣言するしかありません)
この継承がここでどのように機能するかについての知識が不足していると思います。
ModelBase をメタタイプとして定義した理由は、ModelBase とその子を QVariant にラップ/ラップ解除する必要があるためです。