Search code examples
c++forward-declaration

error message: Incomplete type in nested name specifier


I know there are many similar named questions, but I can't figure out my problem after reading through numbers of them.

I am writing a game for a class project.

In class Dungeon, function monsterTurn() needs access to setCurrSp()which is declared as protected in class Hero. Therefore, I tried to add monsterTurn() as a friend function to Hero. Since I had #include "Hero.hpp"in class Dungeon, I used forward declartion, but it throws an error Incomplete type 'Dungeon' named in nested name specifier.

I know declare setCurrSp() as public will solve all these problems, but I don't feel good to leave a setter public. It seems like leaving a backdoor open for unexpected modify. Correct me if I were wrong on this.

Followed are part of the codes.

Hero.hpp

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <vector>
#include "Entity.hpp"
class Dungeon;

class Hero : public Entity{

protected:
    void setCurrSp(int currSp)              { this->currSp = currSp;}
public:
    friend void Dungeon::monstersTurn(vector<Hero>::iterator hero, vector<Hero> heros);
}

Dungeon.hpp

#include <stdio.h>
#include <vector>
#include "Hero.hpp"
#include "Monster.hpp"
class Dungeon{
public:
    void monstersTurn(vector<Hero>::iterator hero, vector<Hero> heroes);
}

Any help will be appreciated.


Solution

  • For the friend declaration

        friend void Dungeon::monstersTurn(vector<Hero>::iterator hero, vector<Hero> heros);
    

    the forward declaration

    class Dungeon;
    

    is not sufficient.

    Demo:

    class Dungeon; // forward declaration
    
    class Hero {
      friend void Dungeon::takeHero(Hero&);
    };
    
    class Dungeon {
      public:
        void take(Hero&);
    };
    

    Output:

    main.cpp:5:38: error: invalid use of incomplete type 'class Dungeon'
        4 |   friend void Dungeon::takeHero(Hero&);
          |                                      ^
    main.cpp:1:7: note: forward declaration of 'class Dungeon'
        1 | class Dungeon; // forward declaration
          |       ^~~~~~~
    

    Live Demo on coliru

    The class Hero needs a ful declaration of class Dungeon to "know" its members.

    For a friend class declaration, a forward declaration is sufficient:

    class Dungeon; // forward declaration
    
    class Hero {
      friend class Dungeon;
    };
    
    class Dungeon {
      public:
        void take(Hero&);
    };
    

    Output:

    (none) – compiled without complaints

    Live Demo on coliru