Search code examples
c++includeforward-declaration

Forward declaration overriding full definition


I know there are some topics on forward declaration, but after reading them, they don't seem to match this situation. I usually understand what is going on, a full definition is required to allocate. However, I really think I have a full definition here so I'm confused.

//game.h
#include "wizard.h"
#include "warrior.h"
#include "archer.h"

#include "fighter.h"

#ifndef GAME_H
#define GAME_H

enum movetype{
    BOOST,
    ATTACK,
    SPECIAL,
    SHIELD
};

struct move{
    enum movetype type;
    fighter * source;
    fighter * target;
};

class game{
public:
    game();
    ~game();
    void execmove(move&);
    bool trymove();

private:
    bool turn;
    fighter*  t1 [3];
    fighter*  t2 [3];
};

#endif

So in game I include all the other classes In fighter I forward declare warrior:

//fighter.h
#ifndef FIGHTER_H
#define FIGHTER_H

class fighter;
class warrior;

struct link {
    fighter * warrior;
    fighter * target;
};

class fighter{
private:


public:
    fighter();
    virtual ~fighter();
    void action(int, fighter*);
    virtual void special(fighter*);
    void attack(fighter*);
    void defend();
    void tick();
    void damage(int,int);
    void createLink(warrior *);
    void removeLink();
protected:
    int hp;
    int priority;
    int boosts;
    int shields;
    bool alive;
    struct link l;
};




#endif

But then when I try to allocate warrior in game:

//game.cpp
#include <iostream>
#include "game.h"


game::game()
{
    t1[0] = new warrior();
    t1[1] = new wizard();
    t1[2] = new archer();

    t2[0] = new warrior();
    t2[2] = new archer();
    t2[1] = new wizard();



}

game::~game()
{
    for(int i = 0; i<3; i++)
    {
        delete t1[i];
        delete t2[i];
    }
}


void game::execmove(move& m)
{

}

I get:

game.cpp:9:14: error: allocation of incomplete type 'warrior'
        t1[0] = new warrior();
                    ^~~~~~~
./fighter.h:7:7: note: forward declaration of 'warrior'
class warrior;
      ^
game.cpp:13:14: error: allocation of incomplete type 'warrior'
        t2[0] = new warrior();
                    ^~~~~~~
./fighter.h:7:7: note: forward declaration of 'warrior'
class warrior;

It seems like that fact that I forward declared makes the compiler ignore the fact that I also included the full definition which is really odd. I'm wondering if there is something that I am missing because I don't know how to fix it if a forward declaration makes the full definition get ignored.

Bottom line: Why can't I allocate warrior since I included the full warrior.h file in game.h?

Here is warrior.h:

#include "fighter.h"

#ifndef FIGHTER_H
#define FIGHTER_H

class warrior{
public:
    warrior();
    ~warrior();
    void special(fighter);
private:


};

#endif

Solution

  • Change warrior.h to: (i.e. correct include guards)

    #ifndef WARRIOR_H
    #define WARRIOR_H
    
    #include "fighter.h"
    
    class warrior{
    public:
        warrior();
        ~warrior();
        void special(fighter);
    private:
    
    
    };
    
    #endif
    

    Or better still use #pragma once if supported