2017-06-02 76 views
0

我是一年級的大學生,不知道關於CS的一切,所以請耐心等待我的新鮮感,這是我的第一個問題。3級與循環之間的循環依賴性問題

對於一項任務,我們正在製作口袋妖怪的虛擬版本去實踐使用C++中的多態,並且我遇到了一些編譯錯誤。這裏有三個文件,只需在它們的代碼樣本:

#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文件爲每個小寵物類型(例如Rock)定義一些虛擬功能的父類。我得到的錯誤是,當我編譯這一切,我得到的東西,說:

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

口袋妖怪需要一個派生類的事件,這樣的事件指針可以指向另一個位置班級可以指向任務的口袋妖怪,pokestop,或洞穴,我一直在網上查找幾個小時,不知道該怎麼做。我將不勝感激幫助!如果您需要更多信息或其他信息,請告知我,這是我第一次發佈問題。

回答

0

您需要一些前向聲明。

在Event.h中,您可以將class Trainer;而不是#include "Trainer.h"。在Trainer.h中,您可以輸入class Pokemon;而不是#include "Pokemon.h"

爲了實際使用其他類,您可能需要在相應的源文件中包含適當的頭文件。但是通過避免在頭文件中包含,你擺脫了循環依賴問題。

Pokemon.h必須繼續到#include "Event.h",因爲您繼承Event,這需要一個完整的定義。

+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 
使用多態(虛擬函數)時

,你必須始終基類的析構函數虛也。使派生類析構函數也是虛擬的也很好,但它不是必需的。