Tony
Tony

Reputation: 253

How to avoid header file duplication?

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

Upvotes: 2

Views: 341

Answers (2)

Alok Save
Alok Save

Reputation: 206518

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"

Upvotes: 1

Abhinav Singh
Abhinav Singh

Reputation: 2651

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.

Upvotes: 0

Related Questions