How to avoid header file duplication? - c++

In my program I got two header files named "invader.h" and "game.h". In game.h I include invader.h, and because I wanto to pass a pointer of the current game instance to an invader instance. I also include game.h in invader.h, but I got compile error. If I remove game.h from invader.h, it works fine. I already added include guard in each header files. Based on what I have found so far, I added a forward declaration of game class in invader.h, because what I need, is a pointer to the game instance in invader.h. But when I want to call a function of game in invader.cpp, it says pointer to incomplete class type is not allowed. What should I do to solve this problem?
Game.h
#ifndef GAME_H
#define GAME_H
#include "Tank.h"
#include "Invader.h"
#include "Block.h"
#include "Bullet.h"
class Game
{
private:
Tank tank;
Invader invaders[11][5];
Block blocks[4];
bool logicRequiredThisLoop = false;
public:
Game();
void initEntities();
Tank* getTank(){return &tank;};
Invader* getInvaders(){return &invaders[0][0];};
Block* getBlocks(){return &blocks[0];};
void updateLogic();
};
#endif
Invader.h
#ifndef INVADER_H
#define INVADER_H
#include "Entity.h"
class Game; //forward declaration of class Game
class Invader: public Entity
{
private:
Game* game;
public:
Invader(){};
Invader(Game*,char*,int,int,int,int,int,int);
void move(long delta);
void doLogic();
};
#endif
Invader.cpp
#include "Invader.h"
Invader::Invader(Game* game,char* sprite,int x,int y,int dx,int dy,int width,int height):Entity(sprite,x,y,dx,dy,width,height)
{
this->game = game;
}
void Invader::move(long delta)
{
if ((dx<0)&&(x<=10))
{
game->updateLogic();
}
if ((dx>0)&&(x>=390))
{
dx = -dx;
y -= dy;
}
x+=dx;
}
in Invader.cpp when I try to call updateLogic() which is a member function of Game class, an error occurs saying the pointer to an incomplete class is not allowed
Actually to be simple the most basic thing I want to know here is: in my code Game class has an invader type member variable, so how can I call member functions of Game class in invader class?li,e I said if I include Invader.h in Game.h and include Gameh.h in Invader.h an compile error occurs.
this is what in get when I include Game.h in Invader.h:
1>ClCompile:
1> Invader.cpp
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(13): error C2146: syntax error : missing ';' before identifier 'invaders'
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): error C2143: syntax error : missing ';' before '*'
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): warning C4183: 'getInvaders': missing return type; assumed to be a member function returning 'int'
1>c:\users\tony\documents\info3220\spaceinvader\spaceinvader\basicwogl\game.h(21): error C2065: 'invaders' : undeclared identifier

what should i do to solve this problem?
As a First understand what an Incomplete type means:
What leads to incomplete types?
If you cannot use Forward declarations without the type being Incomplete type then you shoud re-visit your design because something is wrong there.
You will need to provide the source code if you need a more detailed answer.
EDIT:
You need to include Game.h in Invader.cpp.
//Invader.cpp
#include "Invader.h"
#include "Game.h"

I will explain this in reference to two files i have at my local box right now.
server.h and worker.h
server.h:
#ifndef SERVER_H_
#define SERVER_H_
typedef struct _conf conf;
typedef struct _worker worker;
typedef struct _logger logger;
typedef struct _server server;
struct _server {
/* config */
conf *cfg;
/* socket */
int fd;
struct event_base *base;
struct event *signal;
/* workers */
worker **w;
/* log */
logger *log;
};
...
...
#endif /* SERVER_H_ */
worker.h
#ifndef WORKER_H_
#define WORKER_H_
#include <pthread.h>
typedef struct _server server;
typedef struct _worker worker;
struct _worker {
pthread_t t;
struct event_base *base;
struct evhttp *http;
server *s;
};
...
...
#endif /* WORKER_H_ */
As you can see both server and worker structs make a reference to each other which is solved by forward declarations at the top of .h files: e.g.
typedef struct _worker worker;
at top of server.h is sufficient for it to make a reference to worker struct.
You may want to check complete files for further reference here: https://github.com/abhinavsingh/pulsar/tree/master/include
Hope that helps.

Related

error C2062: type 'void' unexpected in signal declaration in QT

I am a newbie, I am writing a header file in which I am declaring a class which will emit a signal. So I declare my class with a constructor, two int variables which I make private, and then I define my signal. Here is my .h file:
#ifndef KEYBOARD_H
#define KEYBOARD_H
class KeyBoard{
public:
KeyBoard();
int keyboard_update();
private:
int level;
int sub_level;
signals:
void send_to_MBU(QString message);
};
#endif
Now In .cpp part, I am just emitting a signal in the constructor.Here is the code in .cpp part:
#include "KeyBoard.h"
KeyBoard::KeyBoard()
{
level = 0;
sub_level = 0;
emit send_to_MBU("PRESS ENTER TO SELECT TRAIN"):
}
int KeyBoard::keyboard_update()
{
return 1;
}
But when I am compiling my code, I am getting this error in my signal declaration:
error C2062: type 'void' unexpected
For me, the code looks fine. But as am newbie. I can't figure out the issue. So, please help me to resolve this issue.
Need to declare #include <QObject> in .h file to successfully using signals in QT. That's the only thing missing in header file. new code looks like this:-
#ifndef KEYBOARD_H
#define KEYBOARD_H
#include <QObject>
class KeyBoard : QObject{
Q_OBJECT
public:
KeyBoard();
int keyboard_update(char* recieved_key);
private:
int level;
int sub_level;
signals:
void send_to_MBU(QString message);
};
#endif

Using a header file in one code file and then vice versa?

So I've got a bit of a problem (well two but they're unrelated to each other).
I have two headers that look as follows:
Game.h
#ifndef INIT_GAME_H
#define INIT_GAME_H
#include <deps/deps.h>
#include <handlers/RenderHandler.h>
class Game {
private:
RenderHandler* renderHandler; /* <-- This is line 32 in my actual header */
public:
Game() {};
~Game() {};
int initialise();
void handleEvents();
void update();
void render();
void clean();
}; // class Game
#endif // INIT_GAME_H
RenderHandler.h
#ifndef HANDLERS_RENDERHANDLER_H
#define HANDLERS_RENDERHANDLER_H
#include <init/Game.h>
class RenderHandler {
private:
Game* game;
public:
RenderHandler() {};
~RenderHandler() {};
void initialise(Game* game);
void render();
}; // class RenderHandler
#endif // HANDLERS_RENDERHANDLER_H
But the above gives me an error during compilation:
game.h(32): error C2143: syntax error: missing ';' before '*'
game.h(32): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
game.h(32): error C2238: unexpected token(s) preceding ';'
As you've probably guessed, I'm trying to store Game's instance in RenderHandler and vice versa. I'm probably doing it completely the wrong way but I can't figure why it's not working.
Also, all ; are in their right places prior to line 32 in my header file.
EDIT:
after doing the suggested forward declaration, I get the following error (now in RenderHandler.cpp file).
Error: pointer to incomplete class type is not allowed
This is what my code file looks like
RenderHandler.cpp
#include <handlers/RenderHandler.cpp>
void RenderHandler::initialise(Game* game) {
this->game = game;
}
void RenderHandler::render() {
glfwSwapBuffers(game->getPrimaryWindow());
}
Use forward declaration :
#ifndef HANDLERS_RENDERHANDLER_H
#define HANDLERS_RENDERHANDLER_H
// FW declaration of Game
class Game;
class RenderHandler {
private:
Game* game;
public:
RenderHandler() {};
~RenderHandler() {};
void initialise(Game* game);
void render();
}; // class RenderHandler
#endif // HANDLERS_RENDERHANDLER_H

Adding a derived class causes ghost errors [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 7 years ago.
My base class (State.h):
#pragma once
#include <Windows.h>
#define WIN32_LEAN_AND_MEAN
#include <gl\GL.h>
#include <gl\GLU.h>
#include "StateManager.h"
class State
{
public:
virtual ~State();
virtual void update(double dt){}
virtual void render(){}
};
The derived class(State_Test.h):
#pragma once
#include "State.h"
class State_Test : public State
{
public:
State_Test();
~State_Test();
};
The errors it gives are in a different class (StateManager.h):
#pragma once
#include "State.h"
#include <map>
#include <string>
class StateManager
{
public:
StateManager();
~StateManager();
std::map<std::string, State *> m_StateMap;//error C2976: 'std::map' : too few template arguments | error C2065: 'State' : undeclared identifier | error C2059: syntax error: '>'
std::string m_CurrentState;
void AddState(std::string stateId, State *state);//error C2061: syntax error : identifier 'State'
void ChangeState(std::string stateId);
};
Also there's this warning:
Warning 5 warning C4005: '_malloca' : macro redefinition c:\program files (x86)\microsoft visual studio 12.0\vc\include\crtdbg.h 586 1
Syntactically it looks correct, VS doesn't underline anything, and this code had worked before without error. I'm just wondering if anybody has seen this error before or knows what the cause of it is?
You have circular dependency problem: State.h includes StateManager.h, which includes State.h.
Since StateManager uses only pointer to State, remove this include and forward declare State:
#pragma once
//#include "State.h" -> remove this
#include <map>
#include <string>
class State; //-> add this
class StateManager
{
public:
StateManager();
~StateManager();
std::map<std::string, State *> m_StateMap;
std::string m_CurrentState;
void AddState(std::string stateId, State *state);
void ChangeState(std::string stateId);
};

Compiler error C2653: not a class or namespace name

So I have been having this extremely frustrating problem lately with Visual C++ 2012. Up until a few hours ago, I was writing code just fine and everything was working as intended, until I decided to optimize some things and deleted a few classes. I fixed all of the errors that were popping up because of that, e.g. false includes, etc. Unfortunately, after this the VS compiler went crazy. It started giving me errors such as:
Error 14 error C2653: 'Class' : is not a class or namespace name
or even
Error 5 error C2143: syntax error : missing ';' before '}'
Error 4 error C2059: syntax error : '>'
I've checked multiple times, and everything is in it's right place: all headers included, all symbols placed where they should be.
As far as I understand, the problem is not with my code but with the compiler itself... Visual Studio can be really annoying at times, I guess. Anyway, I would really be grateful if someone could help me out on this one.
(By the way, disabling precompiled headers did not work)
Relevant parts of code:
Error 14:
#include "PlayerEntity.h"
PlayerEntity::PlayerEntity(void) {} // This line causes the error
Error 5:
class GameScreen : public BaseScreen
{
public:
...
private:
...
}; // This line causes the error
Error 4:
private:
std::vector<BaseEntity*> _EntityList; // This line causes the error
Whole PlayerEntity.h file:
#ifndef PENTITY_H
#define PENTITY_H
#include "BaseEntity.h"
class PlayerEntity : public BaseEntity
{
public:
PlayerEntity(void);
PlayerEntity(float, float);
virtual ~PlayerEntity(void);
void render(sf::RenderWindow&);
void update();
private:
void init();
};
#endif
Whole GameScreen.h file:
#ifndef GSCREEN_H
#define GSCREEN_H
#include "BaseScreen.h"
#include "BaseEntity.h"
#include "PlayerEntity.h"
class GameScreen : public BaseScreen
{
public:
GameScreen(sf::Vector2u&);
virtual ~GameScreen(void);
void start();
void stop();
void render(sf::RenderWindow&);
void update(void);
void addEntity(BaseEntity*);
void destoryEntity(int id);
private:
std::vector<BaseEntity*> _EntityList;
sf::Vector2u _ScreenDimensions;
};
#endif
Whole BaseEntity.h file:
#ifndef BSENTITY_H
#define BSENTITY_H
#include "Input.h"
#include <SFML/Graphics.hpp>
class BaseEntity
{
public:
BaseEntity(void);
virtual ~BaseEntity(void);
sf::Vector2f position;
virtual void update(void);
virtual void render(sf::RenderWindow&);
void compare(BaseEntity*);
protected:
sf::Texture *_EntityTexture;
sf::Sprite _EntitySprite;
bool _isAlive;
int _id;
virtual void init();
};
#endif
Whole Input.h file:
#ifndef INPUT_H
#define INPUT_H
#include "ScreenSystem.h"
#include <SFML/Window.hpp>
class Input
{
public:
Input(void);
Input(sf::RenderWindow*);
virtual ~Input(void);
static bool keyPressed(int);
static bool keyReleased(int);
static bool mouseHeld(int);
static bool mouseReleased(int);
private:
static sf::RenderWindow *_Window;
};
#endif
Whole ScreenSystem.h file:
#ifndef GHANDLER_H
#define GHANDLER_H
#include "BaseScreen.h"
#include "MenuScreen.h"
#include "GameScreen.h"
#include <SFML/Window.hpp>
class ScreenSystem
{
public:
ScreenSystem(void);
ScreenSystem(sf::RenderWindow*);
virtual ~ScreenSystem(void);
BaseScreen *getCurrentScreen(void);
void setScreen(int);
private:
int _currentScreenID;
std::vector<BaseScreen*> _Screens;
sf::RenderWindow *_Window;
};
#endif
You have a circular dependency in your headers. BaseEntity.h includes Input.h, which includes ScreenSystem.h, which includes GameScreen.h, which in turn re-includes BaseEntity.h. This leads to class names appearing before they are declared, causing compilation failure.
To avoid this, do not include headers unnecessarily. For example, do not include Input.h from BaseEntity.h, since it's not needed at all; and do not include BaseScreen.h from ScreenSystem.h since only a declaration class BaseScreen; is needed, not the complete class definition.
Also, check that you do not have duplicate header guards. Some of them do not match the header name (e.g. GHANDLER_H for ScreenSystem.h), which makes me think that they may have been accidentally copied from other headers. Finally, don't use reserved names like _EntitySprite for your own symbols; for simplicity, avoid leading or double underscores.
Did you copy the error messages into your question or did you retype them? Because error 14 has 'Class' with a capital C which is almost certainly not right.
Also, you should use as few include directives in your header files as possible. For example, GameScreen doesn't use PlayerEntity, so you can remove that include and BaseEntity is only used via pointer so you can replace
#include "BaseEntity.h"
with a forward declaration
class BaseEntity;

Class header files

main.cpp
int main()
{
return 0;
}
cell.h
#pragma once
class _cell {};
cell.cpp
#include "cell.h"
experiment.h
#pragma once
class _experiment
{
_cell cell;
};
experiment.cpp
#include "experiment.h"
#include "cell.h"
Error:
experiment.h(5): error C2146: syntax error : missing ';' before identifier 'cell'
experiment.h(5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
experiment.h(5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
This has been driving me nuts. Any help? Thanks!
You have to #include <cell.h> from experiment.h as otherwise _cell is not defined when used in experiment.h.
Move the include from cell.cpp to the .h
.h:
#pragma once
#include "cell.h"
class _experiment
{
_cell cell;
};
.cpp:
#include "experiment.h"
Classes need the definition of members to contain instances of them.