简体   繁体   English

我的文件依赖关系有什么问题?

[英]What's wrong with my file dependencies?

I have a program using 3 header files and 3 .cpp files in addition to main.cpp. 我有一个程序使用main.cpp之外的3个头文件和3个.cpp文件。 I'm using VC++ 2008. 我正在使用VC ++ 2008。

Here's the setup. 这是设置。 All three headers are guarded with #ifndef HEADERNAME_H, etc. Also all three headers have corresponding .cpp files, which #include their respective headers. 这三个标头均由#ifndef HEADERNAME_H等保护。另外,所有三个标头都有对应的.cpp文件,其中#包括它们各自的标头。

/* 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 { ... };

I'm getting compiler errors for instantiating the three Foo's inside of Moo.h: 我在实例化Moo.h中的三个Foo时遇到编译器错误:

error C2079: 'Moo::setVarA' uses undefined class 'Foo' 错误C2079:“ Moo :: setVarA”使用未定义的类“ Foo”

I included Foo.h right there, so why is it undefined? 我就在其中包括Foo.h,为什么它没有定义? This is the only file that includes Foo.h. 这是唯一包含Foo.h的文件。 I even tried declaring Foo by placing 'class Foo;' 我什至尝试通过放置“ Foo类”来声明Foo; before my declaration of class Moo. 在我宣布Moo类之前。

I also have #defines in my Foo.h file that are also causing compiler errors when I use them in Moo.h. 我的Foo.h文件中也有#define,当在Moo.h中使用它们时也会引起编译器错误。 (undeclared identifier error C2065). (未声明的标识符错误C2065)。

It seems like Foo.h isn't getting included because Moo.h can't find anything defined/declared in it. 似乎没有包含Foo.h,因为Moo.h找不到在其中定义/声明的任何内容。 What's going on? 这是怎么回事?

My actual code is long, but here you go (it's a mario platformer game btw): 我的实际代码很长,但是您可以继续(这是马里奥平台游戏btw):

This would be Foo.h: 这将是Foo.h:

//**************************
//  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

This would be "Moo.h." 这将是“ Moo.h”。 Note the many private Animation members, all causing errors: 请注意许多私人动画成员,所有这些都会导致错误:

//**************************
//  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

This would be "mainHeader.h": 这将是“ 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

Here's main.cpp: 这是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....

You need a forward declaration for class Foo. 您需要对Foo类进行前向声明。 For more information refer to item 31 of "Effective C++, Third Edition". 有关更多信息,请参见“ Effective C ++,第三版”的项目31。 Note: if you forward declare Foo that means your class Moo will only be able to have pointers of type Foo. 注意:如果您向前声明Foo,则意味着您的Moo类将只能具有Foo类型的指针。

If something includes Foo.h this is what happens (the arrows show dependency): 如果某些内容包含Foo.h,则将发生这种情况(箭头显示依赖性):

Foo.h --includes--> mainHeader.h --includes--> Moo.h --includes--> Foo.h Foo.h --includes-> mainHeader.h --includes-> Moo.h --includes-> Foo.h

Note that when class Moo is specified the second Foo.h is not included due to your guards, also class Foo has not been declared yet because that happens after including mainheader.h 请注意,当指定Moo类时,由于您的警卫而未包括第二个Foo.h,因此尚未声明Foo类,因为这在包含mainheader.h之后发生

The best tool for debugging these sorts of situations is the compiler's "dump preprocessed output to a file" option. 调试此类情况的最佳工具是编译器的“将预处理后的输出转储到文件中”选项。 If you enable this, you'll most likely see the problem right away. 如果启用此功能,则很可能会立即发现问题。 Check your compiler options for how to enable it. 检查您的编译器选项以了解如何启用它。

Another problem to watch out for is the use of 'using namespace' statements - you should not use these in header files at all. 需要注意的另一个问题是“使用命名空间”语句的使用-您根本不应该在头文件中使用这些语句。

This is to avoid ambiguities for modules that include lots of different header files. 这是为了避免包含大量不同头文件的模块的歧义。

So, yes, without it you will need to do lots of std::vector, std::list etc which can be a pain. 因此,是的,没有它,您将需要执行很多std :: vector,std :: list等操作,可能会很痛苦。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM