Inheritance & "Base Class Undefined"

C6cb6c90c411f01492653729e7548a50
0
Flamesilver 101 Apr 16, 2011 at 13:10

I’m having a problem compiling code with inheritance across multiple files. Getting 300+ errors right now, but I think it’s a lot of “rough code” and a lot of dependencies issues.

The first error I get is “…\gameform.h(16) : error C2504: ‘GameObject’ : base class undefined”

Here’s the base class in a file called “GameObject.h”

#ifndef _GameObject_h_
#define _GameObject_h_

#include "GameSpace.h"

class GameObject {

public:

    GameSpace* GS;

    GameObject ( GameSpace* in_GS = NULL ) : GS ( in_GS )
    {
    }

    virtual GameObject& item() { return *this; };   // to be overridden
                                                    // item() will return a reference to the most derived version of itself
};

#endif

Here’s “GameForm.h”

#ifndef _GameForm_h_
#define _GameForm_h_

#include "GameObject.h"
#include "DarkGDK.h"
#include "FulcrumPhy.h"
#include "TicketSystem.h"
#include "GameCore.h"
#include "GameState.h"

#include <map>



class GameForm : GameObject {

public:

    int         formid;             // GDK id # for the actor / main mesh object
    StateSpace  States;             // States table of the Form
    GameEntity  *ownerEntity;       // Entity who owns this


    // ************ CTOR & DTOR ***************
    GameForm ( GameSpace* in_GS, GameEntity* in_ownerEntity ) : ownerEntity( in_ownerEntity )
        : GameObject ( in_GS )
        {   formid = GameCore::TS->getTicket("Form");  }

    ~GameForm () {
        GameCore::TS->releaseTicket("Form", formid);
        States.clearAll();
    }

    // ******** overrides ***********
    virtual GameForm&       item() { return *this; }

};

class ShipForm : GameForm {

    // ************ CTOR & DTOR ***************
    ShipForm ( GameSpace* in_GS, GameEntity* in_ownerEntity, std::string in_filename, int in_size, D3DXVECTOR3 in_rotation )
        : GameForm( in_GS, in_ownerEntity ) 
    {
        // Creates a Ship by adding all the necessary States
        States.addtoGameSpace (
            new MeshGDK ( &States, formid, in_filename, in_size, in_rotation )
        );
        // States.addtoGameSpace ( new PositionFP() );
    }

    ~ShipForm () {
        
        // delete every state one by one
            
    }

};

#endif

5 Replies

Please log in or register to post a reply.

B2d356f97a3d0dec8ae2d8c1e1fa1c2d
0
Nerd_Skywalker 101 Apr 16, 2011 at 13:40

If you want to inherit a class you must declare it as such:

class Foo : Bar

So that makes your code

#ifndef _GameObject_h_
#define _GameObject_h_

#include "GameSpace.h"

class GameObject : GameSpace {

public:
    GameObject ( GameSpace* in_GS = NULL ) : GameSpace ( in_GS )
    {
    }

    virtual GameObject& item() { return *this; };   // to be overridden
                                                    // item() will return a reference to the most derived version of itself
};

#endif
340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Apr 16, 2011 at 14:32

The problem is probably a circular dependencies in your header structure. GameForm.h includes GameObject.h, and GameObject.h in turn includes GameSpace.h. We can’t look any further, but if the inclusion chain through GameSpace.h somehow ends up in GameForm.h again, you’ll run into problems.

Note that GameObject.h doesn’t actually need to include GameSpace.h in the first place - you’re only working with pointers to GameSpace, so a simple declaration would suffice:

class GameSpace;

class GameObject
{
    GameSpace* GS;
    // ...
};
C6cb6c90c411f01492653729e7548a50
0
Flamesilver 101 Apr 16, 2011 at 19:47

@Nerd_Skywalker

If you want to inherit a class you must declare it as such:

class Foo : Bar

So that makes your code

#ifndef _GameObject_h_
#define _GameObject_h_

#include "GameSpace.h"

class GameObject : GameSpace {

public:
    GameObject ( GameSpace* in_GS = NULL ) : GameSpace ( in_GS )
    {
    }

    virtual GameObject& item() { return *this; };   // to be overridden
                                                    // item() will return a reference to the most derived version of itself
};

#endif

So you’re saying that I have it backwards?

To clarify, GameForm (and GameSpace, and EVERYTHING else in my code) is a derived version of GameObject and so GameForm inherits from GameObject, not the other way around…

So I think I have the order right… unless I’m really backwards…

C6cb6c90c411f01492653729e7548a50
0
Flamesilver 101 Apr 16, 2011 at 19:48

@.oisyn

The problem is probably a circular dependencies in your header structure. GameForm.h includes GameObject.h, and GameObject.h in turn includes GameSpace.h. We can’t look any further, but if the inclusion chain through GameSpace.h somehow ends up in GameForm.h again, you’ll run into problems.

Note that GameObject.h doesn’t actually need to include GameSpace.h in the first place - you’re only working with pointers to GameSpace, so a simple declaration would suffice:

class GameSpace;

class GameObject
{
    GameSpace* GS;
    // ...
};

Ah… so I don’t need to #include if I’m just working with pointers… and I just need a forward declaration. Got it. Will look at my code again.

But I thought the header guard #ifndef #define would’ve taken care of that…

*EDIT* What if I need to use a member of that pointer?

So…

class Derived : Base {

  OtherClass *p_otherclass;

  Derived ( OtherClass* in_p ) {
    p_otherclass = in_p;
    p_otherclass->memberfunction();
  }
};

Would I need to #include “OtherClass.h” if I’m using member functions of that OtherClass?

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Apr 17, 2011 at 18:08

@Flamesilver

Ah… so I don’t need to #include if I’m just working with pointers… and I just need a forward declaration. Got it. Will look at my code again. But I thought the header guard #ifndef #define would’ve taken care of that…

The header guard will only take care of infinite inclusion loops. Say you have a Foo.h that includes Bar.h, and a Bar.h that in turn includes Foo.h.

Now, for another file that includes Foo.h, it will define the header guard for Foo.h, then includes Bar.h (with appropriate header guard), then again includes Foo.h, which does nothing as the header guard of Foo.h is already active. Then it proceeds with the declarations and definitions in Bar.h, and then those in Foo.h

SomeFile.cpp
-> #include Foo.h
  -> #include Bar.h
    -> #include Foo.h
      -> nothing due to header guard of Foo.h
    -> class Bar { /* ... */ };
  -> class Foo { /* ... */ };

So, if Bar needed the definition of Foo, it will never get to it if you include Foo.h first.

Would I need to #include “OtherClass.h” if I’m using member functions of that OtherClass?

Yes, as soon as the compiler needs to know about the contents of the class (such as when accessing members, doing sizeof(), or using it as a base class), then the whole definition is needed. Note that for return types and parameters in function declarations, you don’t need the definition either. In your example, you could choose to implement the function in the source file rather than in the header.

class Foo;

// these are ok
Foo SomethingThatReturnsFoo(); // function declarations
Foo * ptr; // pointers
const Foo & ref = *ptr; // references
UnrelatedType * ptr2 = reinterpret_cast<UnrelatedType*>(ptr); // reinterpret_cast and const_cast using pointers/references.

// these aren't
SomethingThatReturnsFoo(); // caller needs to know how to handle the return type, even though it doesn't do anything with it.
ptr = new Foo(); // constructor needed
ptr->SomeMember(); // member access
size_t size = sizeof(Foo); // size needed
Base * ptrBase = static_cast<Base*>(ptr); // inheritance hierarchy needed for static_cast and dynamic_cast