Jump to content


Inheritance & "Base Class Undefined"


5 replies to this topic

#1 Flamesilver

    New Member

  • Members
  • PipPip
  • 28 posts

Posted 16 April 2011 - 01:10 PM

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



#2 Nerd_Skywalker

    Valued Member

  • Members
  • PipPipPip
  • 215 posts

Posted 16 April 2011 - 01:40 PM

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


Re-dun-dant adj. 1. See redundant

TheNut said:

"Hmm, yes. Strong is the force with this one"

#3 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 16 April 2011 - 02:32 PM

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;
    // ...
};

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#4 Flamesilver

    New Member

  • Members
  • PipPip
  • 28 posts

Posted 16 April 2011 - 07:47 PM

Nerd_Skywalker said:

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...

#5 Flamesilver

    New Member

  • Members
  • PipPip
  • 28 posts

Posted 16 April 2011 - 07:48 PM

.oisyn said:

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?

#6 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 17 April 2011 - 06:08 PM

Flamesilver said:

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.

Quote

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

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.





2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users