2010-11-28 10 views
0

Ich habe diese 2 Dateien, aber die Schnittstelle (und der Compiler) geben mir diesen Fehler, können Sie mir helfen, zu finden, was falsch ist? Ist wirklich seltsam .. sollte ich alle meine Methoden in der .cpp-Datei definieren?"Der Ausdruck sollte einen Klassenzeiger haben" Visual Studio C++ Fehler

//GameMatch.h 
#pragma once 
#include "Player.h" 

namespace Core 
{ 
    class GameMatch 
    { 
    private: 
     const static unsigned int MAX_PLAYERS=20; 
     unsigned int m_HumanControlled; 
     Score* m_LastDeclaredScore; 
     Score* m_LastScore; 
     unsigned int m_MaxPlayers; 
     Player* m_Players[MAX_PLAYERS]; 
     unsigned int m_PlayerTurn; 
     inline void NextTurn() { m_PlayerTurn=(m_PlayerTurn+1U)%m_MaxPlayers; } 
    public: 
     GameMatch(void); 
     ~GameMatch(void); 
     void RemovePlayer(Player* _player); 
     inline Player* getPlayingPlayer() { return m_Players[m_PlayerTurn]; } 
    }; 
} 

und

//Player.h 
#pragma once 
#include "IController.h" 
#include "GameMatch.h" 
#include <string> 
#include <Windows.h> 

using namespace Core::Controller; 
using namespace std; 

namespace Core 
{ 
    class Player 
    { 
    private: 
     IController* m_Controller; 
     unsigned int m_Lives; 
     GameMatch* m_GameMatch; 
     string m_Name; 
     bool m_TurnDone; 
    public: 
     inline void Die() 
     { 
      m_Lives-=1U; 
      if (m_Lives<1) m_GameMatch->RemovePlayer(this);//m_GameMatch is the first error 
     } 
     inline const string& getName() { return m_Name; } 
     inline bool IsPlayerTurn() { return (m_GameMatch->getPlayingPlayer()==this); }//m_GameMatch is the second error 
     virtual void Play()=0; 
     inline Player(GameMatch* _gameMatch,const char* name,unsigned int lives=3) 
     { 
      m_GameMatch=_gameMatch; 
      m_Name=name; 
      m_Lives=lives; 
     } 
     inline void WaitTurn() { while(!IsPlayerTurn()) Sleep(1); } 
     virtual ~Player() 
     { 
      delete m_Controller; 
     } 
    }; 
} 

Aber wie Sie sehen können, m_GameMatch ist ein Zeiger, so verstehe ich nicht, warum dieser Fehler, vielleicht für "rekursive Inklusion" von Header-Dateien ...

UPDATE 1:

//GameMatch.h 
#pragma once 
#include "Score.h" 
#include "Player.h" 

namespace Core 
{ 
    class GameMatch 
    { 
    private: 
     const static unsigned int MAX_PLAYERS=20; 
     unsigned int m_HumanControlled; 
     Score* m_LastDeclaredScore; 
     Score* m_LastScore; 
     unsigned int m_MaxPlayers; 
     Player* m_Players[MAX_PLAYERS]; 
     unsigned int m_PlayerTurn; 
     inline void NextTurn(); 
    public: 
     GameMatch(void); 
     ~GameMatch(void); 
     void RemovePlayer(Player* _player); 
     inline Player* getPlayingPlayer(); 
    }; 
} 

und

//Player.h 
#pragma once 
#include "IController.h" 
#include "GameMatch.h" 
#include <string> 
#include <Windows.h> 

using namespace Core::Controller; 
using namespace std; 

namespace Core 
{ 
    class Player 
    { 
    private: 
     IController* m_Controller; 
     unsigned int m_Lives; 
     GameMatch* m_GameMatch; 
     string m_Name; 
     bool m_TurnDone; 
    public: 
     inline void Die(); 
     inline const string& getName(); 
     inline bool IsPlayerTurn(); 
     virtual void Play()=0; 
     inline Player(GameMatch* _gameMatch,const char* name,unsigned int lives=3); 
     inline void WaitTurn(); 
     virtual ~Player(); 
    }; 
} 

Dies sind die 2-Header jetzt, es ist aber immer noch nicht funktioniert, wenn ich in GameMatch.h nicht Player.h sind und uns auf eine Klasse auf diese Weise erklären: Klasse-Spieler; Es funktioniert, aber was ist, wenn ich einige Player-Methoden verwenden möchte? Ich sollte alles weiterleiten ... deklariere alles ... ist das nicht das, wofür Header-Dateien gemacht werden? Ich kann eine Header-Datei an vielen Stellen einfügen ... warum kann ich das in diesem Fall nicht tun?

LÖSUNG: Die Antwort ist von Alf P. Steinbach im Chat: ja, und die Antwort, die Sie scheint bekam richtig. Die zyklische Header-Abhängigkeit ist ein Problem. es könnte auch andere Probleme geben, aber die zyklische Abhängigkeit ist groß. Sie benötigen keine vollständige Definition einer Klasse, um T * zu verwenden. so die übliche Brechen des Zyklus ist nur eine Klasse voraus erklären, wie

class Player; 

, die den Compiler sagt, dass Spieler eine Klasse ist, so können Sie Player * und Spieler &, verwenden und sogar Mitgliederfunktionen erklären das return Player (obwohl Sie eine solche Funktion erst definieren können, wenn die Player-Klasse vollständig definiert ist) Und als konkretes Beispiel ist für die Core :: GameMatch-Klassendefinition nur eine Vorwärtsdeklaration der Klasse Player erforderlich. dann in der Implementierungsdatei können Sie "player.h" einschließen. , wenn es für die GameMatch-Implementierung benötigt wird. wenn Sie die Dateien als kleine Boxen und zeichnen Pfeile zeichnen enthalten zu zeigen, werden Sie sehen, dass das, erklärt er diese die zyklischen Abhängigkeit

sagen loswird, dass die Antwort, die ich bekam die richtige ist, so bin ich ll mark OJ

Antwort

1

Sie sollten auf jeden Fall die zyklische Header-Include vermeiden.

Teilen Sie den Inhalt Ihrer Funktionen in .cpp-Dateien auf, anstatt alles in die Header-Dateien zu schreiben. Auch anstelle von #include Dinge jedes Mal, nur vorwärts deklarieren statt.

Wenn Sie das zyklische Include entfernen, funktioniert der Code höchstwahrscheinlich.

+0

Bohren ... Ich werde es versuchen, danke –

+3

Bohren? Ich bin nicht hier, um dich zu begeistern, ich bin hier, um das Problem zu lösen. Wenn Ihnen die Lösung langweilig erscheint, schreiben Sie eine interessantere Frage. –

+0

Nicht langweilig Antwort ...langweilige Dinge zu tun, sorry, ich wollte dich nicht beleidigen –