2017-06-02 12 views
0

私はまだCSについてすべてを知っていない初年度の大学生ですから、私の新しさに耐えてください。これが私の最初の質問です。3つのクラスと継承を持つ循環依存性の問題

割り当てのために、私たちはC++で多態性を使ってPokemon Goの偽のバージョンを作成していますが、いくつかのコンパイラエラーが発生しています。

#ifndef EVENT_H 
#define EVENT_H 

#include <string> 
#include "Trainer.h" 

class Event{ 
    protected: 
     std::string title; 
    public: 
    Event(); 
    ~Event(); 

    virtual void action(Trainer) = 0; 

}; 
#endif 

Trainer.h:

#ifndef TRAINER_H 
#define TRAINER_H 
#include "Pokemon.h" 
class Trainer{ 
    private: 
     Pokemon* pokemon; 
     int num_pokemon; 
    public: 
     Trainer(); 
     ~Trainer(); 
    //include accessors and mutators for private variables  
}; 
#endif 

Pokemon.h:

#ifndef POKEMON_H 
#define POKEMON_H 
#include "Event.h" 
#include <string> 
class Pokemon : public Event{ 
    protected: 
     std::string type; 
     std::string name; 
    public: 
     Pokemon(); 
     ~Pokemon(); 
     virtual bool catch_pokemon() = 0; 

}; 
#endif 

trainer.hファイルがあるここではそれらのコードのほんの一例との3つのファイルがありますいくつかの仮想関数を定義するだけの各ポケモンタイプ(例えばRock)の親クラス。イベントポインタが別の場所で指し示すことができるように

Pokemon.h : 5:30: error: expected class-name befoer '{' token: 
    class Pokemon : Event { 

ポケモンは、イベントへの派生クラスである必要があります:私はこのすべてをコンパイルしていると私が言う何かを得るとき、私は取得していますエラーがありますポケモン、ポケストップ、または洞窟のいずれかを指すことができます。私は何時間もオンラインで探していて、何をすべきか分かりません。私は助けに感謝します!もう一度情報が必要な場合はお知らせください。質問を投稿するのは初めてです。

答えて

0

いくつかの前方宣言が必要です。

012では、#include "Trainer.h"の代わりにclass Trainer;を入れることができます。 Trainer.hで#include "Pokemon.h"の代わりにclass Pokemon;を入力することができます。

おそらく、他のクラスを実際に使用するには、対応するソースファイルに適切なヘッダーを含める必要があります。しかし、ヘッダーファイルのインクルードを避けることで、循環依存関係のトラブルから脱却することができます。

完全な定義が必要なEventを継承しているので、Pokemon.hは#include "Event.h"に続ける必要があります。

+0

ありがとうございました!私は前方宣言の使用について他の質問をしましたが、あなたが2つのクラスを使用していた場合にのみ役立っていました。それらを使うことには欠点がありますか、あるいはオブジェクト指向のものにはかなり必要ですか? – Dula

0

クラスに使用する必要がある型を後で定義するために、前方宣言を使用します。サイズがわかっている状況では前方宣言を使用できますが、ポインターと参照は、それらが指すタイプに関係なく常に同じサイズです。その後、

#ifndef EVENT_H 
#define EVENT_H 

#include <string> 

class Trainer; 
class Event 
{ 
protected: 
    std::string title; 

public: 
    Event(); 
    virtual ~Event(); 

    virtual void action(Trainer* const trainer) = 0; 

}; 
#endif 

その後、

#ifndef TRAINER_H 
#define TRAINER_H 

class Pokemon; 
class Trainer 
{ 
private: 
    Pokemon* const pokemon; 
    int numPokemon; 
public: 
    Trainer(); 
    ~Trainer(); 
}; 
#endif 

#ifndef POKEMON_H 
#define POKEMON_H 
#include "Event.h" 
#include <string> 
class Pokemon : public Event 
{ 
protected: 
    std::string type; 
    std::string name; 
public: 
    Pokemon(); 
    virtual ~Pokemon(); 
    virtual bool catchPokemon() = 0; 
}; 
#endif 

多型(仮想関数)を使用して、あなたはいつもあまりにも基底クラスのデストラクタを仮想にする必要があります。派生クラスのデストラクタを仮想にすることもいいですが、必須ではありません。