7

I can't solve this circular dependency problem; always getting this error: "invalid use of incomplete type struct GemsGame" I don't know why the compiler doesn't know the declaration of GemsGame even if I included gemsgame.h Both classes depend on each other (GemsGame store a vector of GemElements, and GemElements need to access this same vector)

Here is partial code of GEMELEMENT.H:

#ifndef GEMELEMENT_H_INCLUDED
#define GEMELEMENT_H_INCLUDED

#include "GemsGame.h"

class GemsGame;

class GemElement {
    private:
        GemsGame* _gemsGame;

    public:
        GemElement{
            _gemsGame = application.getCurrentGame();
            _gemsGame->getGemsVector();
        }
};


#endif // GEMELEMENT_H_INCLUDED

...and of GEMSGAME.H:

#ifndef GEMSGAME_H_INCLUDED
#define GEMSGAME_H_INCLUDED

#include "GemElement.h"

class GemsGame {
    private:
        vector< vector<GemElement*> > _gemsVector;

    public:
        GemsGame() {
            ...
        }

        vector< vector<GemElement*> > getGemsVector() {
            return _gemsVector;
        }
}

#endif // GEMSGAME_H_INCLUDED
Warren Young
  • 40,875
  • 8
  • 85
  • 101
Nikola C
  • 315
  • 1
  • 3
  • 11
  • 5
    If you have a forward declaration, you shouldn't also include it. And from what you've shown, both only need a forward declaration. – chris Jul 25 '13 at 17:53

4 Answers4

5

Remove the #include directives, you already have the classes forward declared.

If your class A needs, in its definition, to know something about the particulars of class B, then you need to include class B's header. If class A only needs to know that class B exists, such as when class A only holds a pointer to class B instances, then it's enough to forward-declare, and in that case an #include is not needed.

DUman
  • 2,560
  • 13
  • 16
3

If you deference the pointer and the function is inline you will need the full type. If you create a cpp file for the implementation you can avoid the circular dependecy (since neither of the class will need to include each others .h in their headers)

Something like this:

your header:

#ifndef GEMELEMENT_H_INCLUDED
#define GEMELEMENT_H_INCLUDED

class GemsGame;

class GemElement {
    private:
        GemsGame* _gemsGame;

    public:
        GemElement();
};


#endif // GEMELEMENT_H_INCLUDED

your cpp:

#include "GenGame.h"
GenElement::GenElement()
{
   _gemsGame = application.getCurrentGame();
   _gemsGame->getGemsVector();
}
Luke B.
  • 1,258
  • 1
  • 17
  • 28
1

Two ways out:

  1. Keep the dependent classes in the same H-file
  2. Turn dependency into abstract interfaces: GemElement implementing IGemElement and expecting for IGemsGame, and GemsGame implementing IGemsGame and containing a vector of IGemElement pointers.
Yury Schkatula
  • 5,291
  • 2
  • 18
  • 42
1

Look at the top answer of this topic: When can I use a forward declaration?

He really explains everything you need to know about forward declarations and what you can and cannot do with classes that you forward declare.

It looks like you are using a forward declaration of a class and then trying to declare it as a member of a different class. This fails because using a forward declaration makes it an incomplete type.

Community
  • 1
  • 1
Doug
  • 78
  • 7