2009-03-25 5 views
0

Ich habe ein Programm mit 3 Header-Dateien und 3 .cpp-Dateien zusätzlich zu main.cpp. Ich verwende VC++ 2008.Was stimmt nicht mit meinen Dateiabhängigkeiten?

Hier ist das Setup. Alle drei Header werden mit #ifndef HEADERNAME_H usw. geschützt. Außerdem haben alle drei Header entsprechende .cpp-Dateien, die ihre jeweiligen Header enthalten.

/* main.cpp */ 
    #include "mainHeader.h" 

/* mainHeader.h */ 
    #include <windows.h> 
    #include <iostream> 
    //Others... 
    #include "Moo.h" 

/* Moo.h */ 
    #include "mainHeader.h" 
    #include "Foo.h" 

    class Moo { 
     private: 
     int varA; 
     Foo myFoo1; 
     Foo myFoo2; 
     Foo myFoo3; 

     Public: 
     void setVarA(int); // defined in Moo.cpp 
     //etc 
    }; 

/* Foo.h */ 
    #include "mainHeader.h" 
    class Foo { ... }; 

Ich bin Fehler Compiler immer für die Instanziierung der drei Foo innerhalb von Moo.h:

Fehler C2079: 'Moo :: setVarA' verwendet undefinierte Klasse 'Foo'

I enthalten Foo .h dort, also warum ist es undefiniert? Dies ist die einzige Datei, die Foo.h enthält. Ich habe sogar versucht, Foo zu deklarieren, indem ich 'Klasse Foo' gesetzt habe. vor meiner Deklaration der Klasse Moo.

Ich habe auch #defines in meiner Foo.h-Datei, die auch Compilerfehler verursachen, wenn ich sie in Moo.h verwende. (nicht deklarierter Bezeichnerfehler C2065).

Es scheint, als ob Foo.h nicht aufgenommen wird, weil Moo.h nichts Definiertes/Deklariertes darin finden kann. Was ist los?

Mein eigentlicher Code ist lang, aber hier gehen Sie (es ist ein Mario-Jump'n'Run-Spiel btw):

Dies würde foo.h sein:

//************************** 
// Animation.h 
//************************** 
// Header to Animation class 

#ifndef ANIMATION_H 
#define ANIMATION_H 

#include "../Headers/MarioGame.h" 

#define MAX_ANIMATIONS 58 

extern char* fileAnimations[MAX_ANIMATIONS]; 
extern char marioAnims[MAX_ANIMATIONS][3000]; 
extern char background [3700000]; 

class Animation 
{ 
private: 
    int imageCount; 

public: 
    DWORD lastAnimTick; 
    int lastAnim; 
    int anims[4][2]; 
    DWORD animsTime[4]; 

    // Constructor 
    Animation(); 

    // Mutators 
    void addImage(int left, int right, DWORD time); 
    void defaultAnimation(); 

    // Accessors 
    int getImage(bool facingLeft); 
    int getImageCount(); 
    int getCurLoc(); 
}; 

#endif // ANIMATION_H 

Dies wäre "Moo.h." Beachten Sie die vielen privaten Animations Mitglieder, alle Fehler verursacht:

//************************** 
// Mario.h 
//************************** 
// Header to Mario class 

#ifndef MARIO_H 
#define MARIO_H 

#include "../Headers/MarioGame.h" 
#include "../Headers/Animation.h" 

enum { MARIO_TYPE_SMALL, 
     MARIO_TYPE_BIG, 
     MARIO_TYPE_LEAF }; 

class Animation; 

class Mario 
{ 
private: 
    #pragma region Variable Declarations 
     float xPos; 
     float yPos; 

     float xVel; 
     float yVel; 

     float lastXVel; //used for determining when walk/run decceleration is complete 

     float xAccel; 
     float yAccel; 

     float xSize; 
     float ySize; 

     float halfW; 
     float halfH; 

     bool grounded; 
     bool walking; 
     bool running; 
     bool pRunning; 
     bool jumping; 
     bool hunching; 
     bool gliding; 
     bool flying; 
     bool decelerating; 
     int facing; 

     DWORD pRunTimer; 
     int pChargeLevel; 

     DWORD jumpStart; 

     DWORD glideStart; 

     int type; 

     bool updateXMovement; 
     bool updateYMovement; 

     bool screenUpLock; 

     char marioAnims[MAX_ANIMATIONS][3000]; 

     Animation smallStand; 
     Animation smallWalk; 
     Animation smallRun; 
     Animation smallPRun; 
     Animation smallJump; 
     Animation smallSkid; 

     Animation bigStand; 
     Animation bigWalk; 
     Animation bigRun; 
     Animation bigPRun; 
     Animation bigJump; 
     Animation bigSkid; 
     Animation bigHunch; 

     Animation leafStand; 
     Animation leafWalk; 
     Animation leafRun; 
     Animation leafPRun; 
     Animation leafJump; 
     Animation leafSkid; 
     Animation leafHunch; 
     Animation leafTailWhack; 
     Animation leafGlide; 
     Animation leafFly; 
     Animation leafFalling; 

     Animation* lastAnim; 
    #pragma endregion 

public: 
    //Constructor 
    Mario(); 

    //Mutators 
    void setGlideStart(DWORD g); 
    void setHunching(bool h); 
    void setGliding(bool g); 
    void setFlying(bool f); 
    void setType(int t); 
    void setPChargeLevel(int c); 
    void setPRunTimer(DWORD t); 
    void setScreenUpLock(bool s); 
    void setUpdateXMovement(bool m); 
    void setUpdateYMovement(bool m); 
    void setDecelerating(bool d); 
    void setPos(float x, float y); 
    void setVel(float x, float y); 
    void setAccel(float x, float y); 
    void setSize(float x, float y); 
    void setJumping(bool j); 
    void setJumpStart(DWORD s); 
    void setGrounded(bool g); 
    void setWalking(bool w); 
    void setRunning(bool r); 
    void setPRunning(bool r); 
    void setLastXVel(float l); 
    void setFacing(int f); 
    void defaultAnimations(); 

    //Accessors 
    DWORD getGlideStart(); 
    bool getHunching(); 
    bool getGliding(); 
    bool getFlying(); 
    int getType(); 
    int getPChargeLevel(); 
    DWORD getPRunTimer(); 
    bool getScreenUpLock(); 
    bool getUpdateXMovement(); 
    bool getUpdateYMovement(); 
    bool getDecelerating(); 
    float getXPos(); 
    float getYPos(); 
    float getXVel(); 
    float getYVel(); 
    float getXAccel(); 
    float getYAccel(); 
    bool getJumping(); 
    DWORD getJumpStart(); 
    float getXSize(); 
    float getYSize(); 
    float getHalfW(); 
    float getHalfH(); 
    bool getGrounded(); 
    bool getWalking(); 
    bool getRunning(); 
    bool getPRunning(); 
    float getLastXVel(); 
    int getFacing(); 
    int getAnimation(); 
}; 

#endif // MARIO_H 

Dies wäre "mainHeader.h":

//************************** 
// MarioGame.h 
//************************** 
// Header to MarioGame functions 
// Contains Includes, Defines, Function Declarations, Namespaces for program 

#ifndef MARIOGAME_H 
#define MARIOGAME_H 

//*===================== 
// Defines 
//*===================== 
#define WINDOWED  0     // predefined flags for initialization 
#define FULLSCREEN  1 

#define WNDCLASSNAME "MarioGame"   // window class name 
#define WNDNAME   "Mario Game"  // string that will appear in the title bar 

#define NUM_OF_KEYS  5 
#define KEY_SPACE  0 
#define KEY_UP   1 
#define KEY_DOWN  2 
#define KEY_RIGHT  3 
#define KEY_LEFT  4 
#define KEY_CONTROL  5 

#define GRIDW   2.0f 
#define GRIDH   2.0f 

#define PATHING_SIZE 33 

//*===================== 
// Includes 
//*===================== 
#include <windows.h> 

#include <gl/gl.h> 
#include <gl/glu.h> 

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <math.h> 
#include <WAVEMIX.H> 

#include "../Console/guicon.h" 
#include "../Headers/Mario.h" 



//*===================== 
// Function Declarations 
//*===================== 
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); 
HWND createWindow(HINSTANCE &hinst, int width, int height, int depth); 

void renderFrame(); 
void think(); 
void loadTextures(); 
void WMInit(HINSTANCE, HWND); 

void resize (int width, int height); 
void shutdown(); 

void keyLeft(bool); 
void keyRight(bool); 
void keySpace(bool); 
void keyDownArrow(bool); 

bool checkBoundary(float, float); 
void onPlayerDeath(); 

class Mario; 

//*===================== 
// Namespaces 
//*===================== 

using namespace std; 

//*===================== 
// Global Variable Declarations 
//*===================== 
extern Mario Player; 

extern HDC hdc; 
extern HGLRC hglrc; 
extern HWND hwnd; 

extern int SCRW; 
extern int SCRH; 
extern int SCRD; 

extern DWORD oldTick; 
extern DWORD oldTick2; 
extern DWORD oldPTime; 

extern float pixelZoom; 

extern float screenPosX; 
extern float screenPosY;   

extern float playerScrollMultiplier;  

extern float playerTerminalWalkVel; 
extern float playerWalkAccel;  

extern float playerRunAccel;    
extern float playerTerminalRunVel; 

extern float playerDecel; 

extern float playerPVel; 
extern DWORD playerPRunAchieveTime;  

extern float playerJumpUpVel; 
extern float playerJumpTime; 

extern float gravityAccel; 
extern float playerTerminalFallVel; 

extern float playerTerminalGlideFallVel; 


extern bool keyDown[NUM_OF_KEYS]; 
extern bool lastSpace;   

extern bool drawPathingMap;    

extern float pathing [PATHING_SIZE][5][2];  

#endif   // MARIOGAME_H 

hier main.cpp:

//************************** 
// main.cpp 
//************************** 
// Primary implementation file; handles Win32 interface 


#include "../Headers/MarioGame.h" 
//*===================== 
// WinMain 
//*===================== 
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int nshowcmd) 
{ 
    ... 
} 

//And other functions.... 
+0

Bitte mehr des echten Codes, als Pseudo-Code, der annähert, was Sie denken, dass das (fehlerhafte) Original tut. Alle subtilen Fehler, die echter Code enthält, werden nicht weitergegeben. –

+0

@Adam: Eigentlich ist ein funktionierender Testfall besser. Ich werde nicht seinen ganzen Code lesen. –

Antwort

2

Sie benötigen einen vorwärts Erklärung für die Klasse Foo. Weitere Informationen finden Sie unter Punkt 31 von "Effective C++, Third Edition". Hinweis: Wenn Sie force deklarieren, bedeutet das, dass Ihre Klasse Moo nur Zeiger vom Typ Foo haben kann.

Wenn etwas enthält foo.h das ist, was passiert (die Pfeile zeigen die Abhängigkeit):

foo.h --includes -> mainHeader.h --includes -> Moo.h --includes- -> foo.h

Beachten Sie, dass, wenn Klasse Moo angegeben wird die zweite foo.h nicht aufgrund Ihrer Wachen enthalten, auch Klasse Foo wurde noch nicht erklärt, weil das passiert, nachdem einschließlich mainheader.h

+0

Erstens, ist es möglich, dies ohne Vorwärtsdeklaration und ohne Zeiger, sondern tatsächliche Klassen zu tun? Zweitens, was ist mit einem #define in Foo.h, das nicht von Moo.h gefunden wurde ??? –

+0

Wenn Sie sicherstellen können, dass Foo.h IMMER vor Moo.h enthalten ist, sollten Sie kein Problem haben. Ihr Beispiel zeigt nur Moo.h einschließlich Foo.h, aber ich denke nicht, dass dies der Fall ist. Wie andere vorgeschlagen haben, sollten Sie ein vollständigeres Beispiel veröffentlichen, das fehlschlägt. – Trent

+0

Vielen Dank, Sie haben das Problem gesehen, aber ich brauchte die Preprocessor-Dump-Datei (danke Dan Olsen), damit ich sie sehen kann. –

2

die Das beste Werkzeug zum Debuggen dieser Art von Situationen ist die "dump preprocessed output to a file" Option des Compilers. Wenn Sie dies aktivieren, werden Sie das Problem höchstwahrscheinlich sofort sehen. Überprüfen Sie Ihre Compiler-Optionen für die Aktivierung.

+0

Toller Tipp, das hat mir geholfen, das Problem zu sehen. –

0

Ein weiteres Problem, auf das Sie achten sollten, ist die Verwendung von 'using namespace' Anweisungen - Sie sollten diese nicht in Headerdateien verwenden.

Dies dient zur Vermeidung von Mehrdeutigkeiten für Module, die viele verschiedene Header-Dateien enthalten.

Also, ja, ohne sie müssen Sie viele std :: vector, std :: list usw. tun, die ein Schmerz sein kann.

Verwandte Themen