Search code examples
c++c2079

Error C2079, what order to define classes in


I'm getting a compiler error with this header file:

#ifndef GAME1_H  
#define GAME1_H  
#include "GLGraphics.h"  
#include "DrawBatch.h"  
class GameComponent;  
class Game1 {  
private:  
    GLGraphics graphics;  
 GameComponent components;
 void updateDelegates();  
 void Run();  
};  

class GameComponent {  
private:  
 static int index;  
protected:  
 Game1 game;  
public:  
 GameComponent();  
 GameComponent(Game1 game);  
 void Update(int);  
 void Dispose();  
};  

class DrawableGameComponent: public GameComponent  
{  
private:  
 GLGraphics graphics;  
 DrawBatch drawBatch;  
public:   
 DrawableGameComponent();  
 DrawableGameComponent(Game1);  
 void Draw();  
};  

#endif

I see the problem is that Game1 needs the full definition of GameComponent, and that GameComponent needs the full definition of Game1. I had way too much trouble having these in separate headers, so that's why they're together. Is there any way I can do this without completely changing the implementation of one of the classes?

Thanks!


Solution

  • Think about the computer's memory for a second here.

    class B;
    
    class A {
        byte aa;
        B ab;
    };
    
    class B {
        byte bb;
        A ba;
    };
    
    A x;
    

    Now the question the compiler needs to answer is How much space should I reserve for x?

    Let's see. The first byte of x is byte aa;. Easy enough. That's 1 byte.
    Next comes B ab;. Let's see what's in there.
    The first byte of x.ab is a byte bb;. That's 2 bytes for x so far.
    Next, is a A ba;. Let's see what's in there.
    The first byte of x.ab.ba is a byte aa;. That's 3 bytes for x so far.
    And so on and so forth ad infinitum.
    How big is x? The correct answer is of course *** OUT OF CHEESE ERROR ***.

    The compiler doesn't actually do this because it knows it can't handle this case - so the syntax doesn't allow circular containment in the first place.


    Here's a diagram of the contents of x in this example:
    Diagram


    UPDATE

    Apparently, I forgot to include a solution here. Now that you understand what the problem is, the solution should be pretty simple. Use pointers. Either use a pointer from A to B and let B include A as it already does, or vice versa, or use two pointers. Then, you won't have circular inclusion - if B doesn't include a copy of A but just a pointer to it, that fixes the entire issue here.