Pointers, Class Items and Scope - c++

I can't seem to find the answer but maybe I'm searching the wrong terminology. I am not finding the answer I am looking for in the hits.
I have a bunch of derived classes for a menu system.
I have a CControl derived class that is parent of a CEditBox and a CLabel class. CLabel is nothing more than attaching the text onto an SDL_Surface and then binding it to a texture for openGL to render. CEditBox would be a field for displaying text or gathering text from users like a password box. Obviously, CEditBox could make use of a label for handling the text rendering inside the box. CControl is derived from CComponent.
I cannot declare CLabel inside CEditBox unless I include CLabel in the header but I think I keep getting linker errors doing that even though I have all of my headers wrapped in #ifndef #define class #endif syntax but I'm also a noob. Instead, I have a CComponent* pointer declared since they are derived from that class.
Fine. Now in the constructor for the CEditBox I have:
#include "CLabel.h" //include in .CPP is fine I reckon.
CEditBox::CEditBox() {
CLabel Field; //Create CLabel
InputType = ALL; //Not important for my question related to allowed symbols
Label = &Field; //CComponent pointer to CLabel
}
When this constructor function returns, wouldn't CLabel go out of scope, and thus Feild would be destroyed and now my pointer is pointing at an undefined block of memory? What would be an appropriate way to do this? Is there a better solution?
Thank you
Linker problem
I don't know that the problem exists anymore, but some think this is a more important issue. Well here is the actual code now and you guys can tell me if you think it is done incorrectly.
Base Class CMenuObject
#ifndef _CMENUOBJECT_H_
#define _CMENUOBJECT_H_
class CMenuObject {
protected:
const char* ClassName;
public:
CMenuObject();
virtual const char* Object();
};
#endif
Next Class is CComponent
#ifndef _CCOMPONENT_H_
#define _CCOMPONENT_H_
#include "CMenuObject.h"
class CComponent : public CMenuObject {
protected:
const char* _Name;
int _Tag;
static int _ComponentCount;
static int _IDCount;
public:
CComponent();
virtual const char* Name();
virtual int Tag();
virtual void Tag(int t);
};
#endif
Then comes CControl These would be objects that users would interact with or in some way need control the display (i.e. a timer doesn't need user input) and is a mammoth. Don't mind the function pointer stuff because I have no idea what i'm doing with that yet.. this is my first guess approach to handling events. I think it's limiting because I can't figure out what to do if the function needs to take a parameter but I may not have to, etc... We can gloss over this detail for now.
#ifndef _CCONTROL_H_
#define _CCONTROL_H_
#include "CComponent.h"
class CControl : public CComponent {
protected:
int _X,_Y,_Width,_Height;
float R,G,B,A;
void (*OnClk)();
void (*OnDblClk)();
void (*OnMOver)();
void (*OnMHover)();
void (*OnKDown)();
void (*OnKUp)();
void (*OnFcs)();
bool Visible;
CComponent* Pappy;
public:
CControl();
//Render Control
virtual void Show(); // Show Component
virtual void Hide(); // Hide Component
virtual void OnRender(); // Render Component
virtual bool IsVisible(); // Get Current Visibility Status
//Paramater Control
//Write
virtual void X(int x); // Set Component's X coordinate
virtual void Y(int y); // Set Component's Y coordinate
virtual void Width(int w); // Set Component's Width
virtual void Height(int h); // Set Component's Height
//Read
virtual int X(); // Get Component's X coordinate
virtual int Y(); // Get Component's Y coordinate
virtual int Width(); // Get Component's Width
virtual int Height(); // Get Component's Height
//Display Control
virtual void Color(float r, float g, float b); // Set Color of Component- Multicolored objects, this will be the base or bkg color. Makes alpha 1.0f.
virtual void Color(float r, float g, float b, float a); // Same as above but allows for input of an alpha value.
//Font Control
virtual void FontName(const char* font); // Name of font to use
virtual void FontSize(int pt); // Pt size of font. Or maybe pixel, no idea.
virtual void Text(const char* msg); // Text message to render
//Read
virtual const char* Text(); // Read Text Message
//Interactive Control // These will register call back functions for user events
virtual void OnClick(void (*func)()); // On Single Click
virtual void OnDoubleClick(void (*func)()); // On Double Click
virtual void OnMouseOver(void (*func)()); // On Mouse Over
virtual void OnMouseHover(void (*func)()); // On Mouse Hover
virtual void OnKeyDown(void (*func)()); // On Key Down
virtual void OnKeyUp(void (*func)()); // On Key Up
virtual void OnFocus(void (*func)()); // On Focus
//Other
virtual void Parent(CComponent); // Set Parent
virtual CComponent* Parent(); // Get Parent
};
#endif
Finally my end game headers of CLabel and CEditBox.
#ifndef _CLABEL_H_
#define _CLABEL_H_
#include "CTexture.h"
#include "CFont.h"
#include "CControl.h"
class CLabel : public CControl {
private:
const char* vText;
CFont Font;
CTexture Text_Font;
SDL_Surface* Surf_Text;
int X,Y,vWidth,vHeight;
public:
CLabel();
CLabel(const char* text);
virtual void OnRender();
virtual void OnCleanup();
virtual void Text(const char* msg);
virtual const char* Text();
virtual void FontName(const char* fname);
virtual void FontSize(int pt);
virtual void FontColor(float r, float g, float b);
};
#endif
AND
#ifndef _CEDITBOX_H_
#define _CEDITBOX_H_
#include "CControl.h"
class CEditBox : public CControl {
protected:
CComponent* Label;
int InputType;
public:
CEditBox();
~CEditBox();
virtual void OnRender();
//virtual void OnCleanup();
virtual void OnLoop();
virtual void Text(const char* msg);
virtual const char* Text();
virtual void FontColor(float r, float g, float b);
virtual void OnClick(void (*func)()); // On Single Click
virtual void OnDoubleClick(void (*func)()); // On Double Click
virtual void OnMouseOver(void (*func)()); // On Mouse Over
virtual void OnMouseHover(void (*func)()); // On Mouse Hover
virtual void OnKeyDown(void (*func)()); // On Key Down
virtual void OnKeyUp(void (*func)()); // On Key Up
virtual void OnFocus(void (*func)()); // On Focus
enum {
ALL = 0, //abcdefghijklmnopqrstuvwxyz (and caps) 1234567890!##$%^&*()_+-=[]{}<>\/|"';:,.?
ALPHA_NUMERIC, //abcdefghijklmnopqrstuvwxyz (and caps) 1234567890
ALPHA, //abcdefghijklmnopqrstuvwxyz (and caps)
NUMERIC, //1234567890
PASSWORD, //abcdefghijklmnopqrstuvwxyz (and caps) 1234567890!##$%&. -- Render as *
IP //1234567890 . Maybe fix feild width and force xxx.xxx.xxx.xxx format.
};
};
#endif
[SOLVED]
Today, I found the one dang header not wrapped in #ifndef #define #endif. (it was CTexture which gets called again in CFont. Anyway, the restructure was also incredibly beneficial because I've figured out how to use inheritance and base class pointers, and how derived classes can work with each other. Not to mention many many more things. :)
The route I'm taking for derived class interplay is using a base class pointer that can access the derived classes functions via virtual functions. I use new and delete because that's what I am comfortable with. For everyone that contributed, thank you! They are all good answers.

Stereo typical approaches would be:
the pimpl idiom (Why should the "PIMPL" idiom be used?)
using unique_ptr (Rule of Zero)
Showing the second approach:
//////////// CEditBox.hpp header file
#include <memory>
#include <string>
class CLabel; // forward declaration
class CEditBox
{
public:
CEditBox(std::string const&);
private:
std::unique_ptr<CLabel> _label;
};
The forward declaration avoids the need to include CLabel.hpp. The unique_ptr manages the lifetime _label so we don't have to remember to delete it.
//////////// CLabel.hpp header file
#include <string>
#include "CLabel.hpp"
class CLabel
{
public:
CLabel(std::string const& name)
: _name(name)
{
}
private:
std::string _name;
};
Just a sample, nothing to see here. Let's move on:
///////////// CEditBox.cpp source file
#include "CEditBox.hpp"
#include "CLabel.hpp"
CEditBox::CEditBox(std::string const& name)
: _label(new CLabel(name))
{
}
That's the magic: we integrate it all by include CLabel.hpp as well, and construct it in the initializer list.
///////////// main.cpp source file
#include "CEditBox.hpp"
int main()
{
CEditBox box("Hello world"); // no need to 'know' CLabel here
}
Proof of the pudding is in the compilation: http://ideone.com/zFrJa8

Your thinking is on the correct track. The right approach would be allocating this object dynamically, i.e.
Label = new CLabel;
Don't forget to free memory in destructor:
delete Label;

If I understand your problem correctly, you have two classes which have member variables with each other's class?
For instance:
// A.h
#ifndef A_H
#define A_H
#include "B.h"
class A {
public:
...
private:
B* pB;
};
#endif // A_H
And:
// B.h
#ifndef B_H
#define B_H
#include "A.h"
class B {
public:
...
private:
A* pA;
};
#endif // B_H
And compiling these together causes some form of linker error? If this is the case you can circumvent this by forward declaring the class, so instead of including A.h and B.h you simple write class B; above your declaration of class A and class A; above your declaration of class B, then include the headers in your cpp files. So A.h would look like:
// A.h
#ifndef A_H
#define A_H
class B;
class A {
public:
...
private:
B* pB;
};
#endif // A_H

CLabel Field; should be a member of CEditBox. The real question is the one where you mention 'linker errors' (or whatever it is). That's the problem you should be solving.

Related

C++ friend class invalid use of incomplete type OOP

I have decided learn some OOP and I started get rid of conditionals (I know in this program this in unnecessary but I have to start with simply example).
In class DirectConditions, I have my conditions and I would pass object of SnakeGame by reference to friend class DirectConditions's method and change value of some variables of SnakeGame in DirectConditions's method.
Error:
invalid use of incomplite type 'class DirectConditions::SnakeGame' snakeObj.snake[0].xCoor+=1;
Another Question:
May I take this occasion to ask: this way to get rid of conditionals(if's) is good? I would really appreciate help.
Providing the code:
snakeGame.hpp:
#ifndef _SNAKEGAME_HPP
#define _SNAKEGAME_HPP
#include<string>
#include"directConditions.hpp"
#include<map>
class SnakeGame{
public:
SnakeGame();
void mainLogic();
void check();
friend class DirectConditions;
private:
const int width,height;
int sizeOfSnake;
std::string direction;
std::map<std::string,DirectConditions*> directMap;
struct Snake{ int xCoor,yCoor; }snake[100];
enum Directions{up,down,left,right} directEnum;
void initializeMap();
};
SnakeGame::SnakeGame():width(500),height(500),sizeOfSnake(3){}
void SnakeGame::check(){
for(int i=sizeOfSnake;i>0;--i){
snake[i].xCoor=snake[i-1].xCoor;
snake[i].yCoor=snake[i-1].yCoor;
}
directMap[direction].goToDirection(this);
}
//private fun
void SnakeGame::initializeMap(){
directMap["right"]=new GoRight;
directMap["left"]=new GoLeft;
directMap["up"]=new GoUp;
directMap["down"]=new GoDown;
}
#endif
directConditions.hpp:
#ifndef _DIRECTCONDITIONALS_HPP
#define _DIRECTCONDITIONALS_HPP
#include"snakeGame.hpp"
class DirectConditions{
public:
class SnakeGame;
virtual void goToDirection(SnakeGame&)=0;
virtual ~DirectConditions(){};
};
class GoRight:public DirectConditions{
public:
void goToDirection(SnakeGame& snakeObj){
snakeObj.snake[0].xCoor+=1;
}
};
class GoLeft:public DirectConditions{
public:
void goToDirection(SnakeGame& snakeObj){
snakeObj.snake[0].xCoor-=1;
}
};
class GoUp:public DirectConditions{
public:
void goToDirection(SnakeGame& snakeObj){
snakeObj.snake[0].yCoor+=1;
}
};
class GoDown:public DirectConditions{
public:
void goToDirection(SnakeGame& snakeObj){
snakeObj.snake[0].yCoor-=1;
}
};
#endif
You should avoid including of headers by each other - that's why you're getting "invalid use of incomplete type".
Change those includes to forward declarations and move implementation of methods to cpp files.

C++ multiple inheritance, multiple definition when there isn't?

I'm implementing hardware drivers for an embedded C/C++ project, and trying to make things a bit more flexible for future projects.
I have the vast majority of the work done in LCD.hpp/LCD.cpp, where there's a class that has five virtual functions. Four of these are for twiddling GPIO pins and sending SPI messages, and the fifth is for implementing various fonts. A shortened class declaration is as follows:
//LCD.hpp
#include <cstdint>
#ifndef LCD_HPP
#define LCD_HPP
class LCD {
public:
virtual void write_character(char what) = 0; //Stores data into a buffer in LCD through another function
protected:
virtual void SPI_TX(uint8_t *TXData, uint8_t length, bool ToBeContinued) = 0;
virtual void update_RST(bool pinstate) = 0;
virtual void update_DC(bool pinstate) = 0;
virtual void update_backlight(uint8_t brightness) = 0;
};
#endif
Moving on, I implemented a font-printing write_character as such.
//LCD_FixedWidth.hpp
#include <cstdint>
#include "LCD.hpp"
#ifndef LCD_FIXEDWIDTH_HPP
#define LCD_FIXEDWIDTH_HPP
class LCD_FixedWidth : virtual public LCD {
public:
void write_character(char what);
};
#endif
Now it's time for the various hardware bits.
//LCD_hardware.hpp
#include <cstdint>
#include "LCD.hpp"
#include "LCD_FixedWidth.hpp"
#ifndef LCD_HARDWARE_HPP
#define LCD_HARDWARE_HPP
class LCD_hardware : virtual public LCD {
protected:
void SPI_TX(uint8_t *TXData, uint8_t length, bool ToBeContinued);
void update_RST(bool pinstate);
void update_DC(bool pinstate);
void update_backlight(uint8_t brightness);
};
And then a class to tie it all together, still in LCD_hardware.hpp...
class LCD_meta : public LCD_hardware, public LCD_FixedWidth {
public:
void write_character(char what) { LCD_FixedWidth::write_character(what); };
protected:
void SPI_TX(uint8_t *TXData, uint8_t length, bool ToBeContinued) { LCD_hardware::SPI_TX(TXData, length, ToBeContinued); };
void update_RST(bool pinstate) { LCD_hardware::update_RST(pinstate); };
void update_DC(bool pinstate) { LCD_hardware::update_DC(pinstate); };
void update_backlight(uint8_t brightness) { LCD_hardware::update_backlight(brightness); };
};
#endif
And for all of this, I get a multiple definition of LCD_FixedWidth::write_character(char) error. Anybody see anything I'm missing here? All of my headers are guarded properly, and I can only see one implementation of write_character...
This was caused by having LCD_meta and LCD_hardware in the same header file. The code for the LCD_hardware functions was in an implementation file, so the LCD_meta class didn't actually have those functions defined yet... One class per file!

C++ Event handler with derived classes through a base class array

I have been trying to make a game engine for some time, and for the most part it has been turning out quite well, considering it's the first one i've made. But when I started to make an event send/recieve system with derived classes contained in a base class pointer vector array, I had some trouble making the reciever get the class type and use the proper function; here's what I have:
This is my base class Object:
object.h:
#include "all.h" //Contains '#include "SDL/SDL.h"' and constant variables.
#include <vector>
#include "mask.h" //An unimportant class used for collision checking
class Body;
class Room;
class Object//Objects that belong here are those without step events.
{
public:
vector<vector<Room> > *world_map;//Should hold the address of the world map.
Room *room;//The room holding this object.
unsigned int x;
unsigned int y;
unsigned int pos;//Position of the object in the room's list.
int depth;//The deeper it is, the later it will be drawn.
virtual void draw(SDL_Surface *buffer,int viewx, int viewy){}
virtual void interact(Body *body);//Sends a pointer of this object to the
//the obj_event function of the body calling it.
Object(unsigned int xx=0, unsigned int yy=0,int d=0):x(xx),y(yy),depth(d){}
};
#endif // INSTANCE_H_INCLUDED
object.cpp:
#include "object.h"
#include "body.h"
void Object::interact(Body *body)
{
body->obj_event(this);
}
This is my derived class Body:
body.h:
#ifndef BODY_H_INCLUDED
#define BODY_H_INCLUDED
#include "all.h"
#include "object.h"
class Entity;
class Enemy;
class Player;
class Body : public Object//Objects that belong here are those with step events.
{
public:
int priority;//Decides which body will perform their step event first.
virtual void step()=0;
Body(int xx=0, int yy=0, int d=0, int p=0):Object(xx,yy,d),priority(p){}
//These scripts are for handling objects and bodies it has called through
//interact()
virtual void obj_event(Object *object){}
virtual void obj_event(Entity *entity){}
virtual void obj_event(Enemy *enemy){}
virtual void obj_event(Player *player){}
};
#endif // BODY_H_INCLUDED
there is no body.cpp
This is my derived class of Body, Entity:
entity.h:
#ifndef ENTITY_H_INCLUDED
#define ENTITY_H_INCLUDED
#include "all.h"
#include "body.h"
#include "items.h"
#include <vector>
#include "mask.h"
class Entity : public Body
{
public:
vector<Item> inv;
unsigned int width;
unsigned int height;
Mask mask;
Entity(int xx,int yy,int w,int h,int d=0,int p=0);
void step();
void collide_action(Entity *entity);
virtual void obj_event(Player *player);
virtual void obj_event(Enemy *enemy);
};
#endif // ENTITY_H_INCLUDED
entity.cpp:
#include "entity.h"
#include "room.h"
#include "player.h"
#include "enemy.h"
Entity::Entity(int xx,int yy,int w,int h,int d,int p):Body(xx,yy,d,p),width(w),height(h),mask(xx,yy,w,h,m_rectangle)
{}
void Entity::step()
{
for(int iii=0;iii<room->inv.size();iii++)//Iterates through objects
{
room->inv[iii]->interact(this);
mask.update(x,y,width,height);
}
for(int iii=0;iii<room->index.size();iii++)//Iterates through bodies
{
room->index[iii]->interact(this);
mask.update(x,y,width,height);
}
}
void Entity::collide_action(Entity *entity)
{
if(entity!=this)
{
if (mask_collide(mask,entity->mask))
{
short xchange;
short ychange;
if (entity->x<x)
{
xchange=width-(x-entity->x);
}
else
{
xchange=(entity->x-x)-width;
}
if (entity->y<y)
{
ychange=height-(y-entity->y);
}
else
{
ychange=(entity->y-y)-height;
}
if(abs(xchange)<abs(ychange))
x+=xchange;
else
y+=ychange;
}
}
}
void Entity::obj_event(Player *player)
{
collide_action(player);
}
void Entity::obj_event(Enemy *enemy)
{
collide_action(enemy);
}
This is my derived class of Entity, Player:
player.h:
#ifndef PLAYER_H_INCLUDED
#define PLAYER_H_INCLUDED
#include "all.h"
#include "body.h"
#include "items.h"
#include <vector>
#include "mask.h"
#include "entity.h"
enum keylist
{
kl_left=0,
kl_up=1,
kl_right=2,
kl_down=3,
};
class Player : public Entity
{
public:
SDLKey keys[4]; //List of action's corresponding keys.
Player(int xx,int yy,int w,int h,int d=0,int p=0);
void step();
void draw(SDL_Surface *buffer,int viewx,int viewy);
void interact(Body *body);
};
#endif // PLAYER_H_INCLUDED
player.cpp:
#include "player.h"
#include "room.h"
Player::Player(int xx,int yy,int ww,int hh,int dd,int pp):Entity(xx,yy,ww,hh,dd,pp)
{
//Default keys, can be changed.
keys[kl_left]=SDLK_LEFT;
keys[kl_up]=SDLK_UP;
keys[kl_right]=SDLK_RIGHT;
keys[kl_down]=SDLK_DOWN;
}
void Player::step()
{
Uint8 *key=SDL_GetKeyState(NULL);
if (key[keys[kl_left]])
x-=1;
if (key[keys[kl_right]])
x+=1;
if (key[keys[kl_up]])
y-=1;
if (key[keys[kl_down]])
y+=1;
mask.update(x,y,width,height);
Entity::step();
}
void Player::draw(SDL_Surface *buffer,int viewx,int viewy)
{
FillRect(buffer,x-viewx,y-viewy,width,height,0xFF0000);
}
void Player::interact(Body *body){body->obj_event(this);}
I have another class Enemy, but it's pretty much exactly like player (without the keyboard controls).
Now here's my problem (not error), for every object I want any body to perform an event for, I need to make virtual functions of ALL of them in this base class, that way if any object calls body->obj_event(this), it will pick the proper function with the most derived argument.
For example, if Player called object->interact(this) of an enemy, the enemy would first use it's base class Object's virtual function interact(Body*), which would then check the derived classes if they have an identical function (which enemy does), and then enemy calls body->obj_event(this) of the player body through it's base class, Body. The player body would then first use it's base class Body's virtual function obj_event(Enemy*), which would then check the derived classes if they have an identical function (which Entity does), and then Entity executes obj_event(Enemy*). At least that's how I understand it.
What I'd like to have is a way for any derived class to call interact of any other derived class through it's base function, and would then have it call it's obj_event function for the derived class, without having to have any of the Base classes know about their derived classes.
As I mentioned, this is my first time making an engine, and I'm probably using methods that are completely hectic and error-prone. I was thinking that templates might be able to help out in this situation, but don't know how to implement them.

Inheritance error dilemma: "invalid use of incomplete type" VS "expected class-name"

So I'm trying to get class "Herder" to inherit from class "Mob". But I am getting compiler errors that read as follows:
error: invalid use of incomplete type 'struct Mob'
error: forward declaration of 'struct Mob'
This is what Herder.h looks like:
#ifndef HERDER_H_INCLUDED
#define HERDER_H_INCLUDED
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include "Level.h"
#include "Mob.h"
class Mob;
class Herder : public Mob
{
public:
//Member functions.
Herder(Level* level, int x, int y);
void virtual GameCycle(sf::RenderWindow* App);
void virtual Die();
void Roar();
protected:
float m_RoarCountdown;
float m_RoarTime;
float m_Speed;
bool m_Roaring;
};
#endif // HERDER_H_INCLUDED
Figuring that it must be the class Mob; that is causing this, I remove it, but then I get the following error, refering to the line where the curly braces open:
error: expected class-name before '{' token
This is actually why I originally added the forward declaration - I had thought that the compiler wasn't recognizing Mob in class Herder : public Mob, so I figured I would forward declare.
I don't think it's a case of cyclical dependency, as has been the case in some cases I found via Google - "Mob.h" contains nothing to do with the Herder class whatsoever.
I have tried removing #include "Mob.h" altogether and sticking with just the forward declaration, but that doesn't work either - I get only one error, again:
error: invalid use of incomplete type 'struct Mob'
This is confusing. I've successfully gotten classes to inherit before, and this code seems analogous in all relevant ways to my previous successful attempts.
EDIT: Here are the contents of Mob.h
#ifndef MOB_H_INCLUDED
#define MOB_H_INCLUDED
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include "Level.h"
class Level;
class Mob
{
public:
//Member functions.
Mob(Level* level, int x, int y);
float GetX();
float GetY();
void SetColor(sf::Color color);
void virtual GameCycle(sf::RenderWindow* App) = 0;
void virtual Die() = 0;
void Draw(sf::RenderWindow* App);
protected:
float m_X;
float m_Y;
bool m_Moving;
int m_Health;
sf::Sprite m_Sprite;
Level* pLevel;
};
#endif // MOB_H_INCLUDED
EDIT: Here are the contents of the "Level.h" file. Note that Baby is a child class of Mob in much the same way as Herder; both experience the same errors.
#ifndef LEVEL_H_INCLUDED
#define LEVEL_H_INCLUDED
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include "Tile.h"
#include "Herder.h"
#include "Baby.h"
class Tile;
class Herder;
class Baby;
/// LEVEL
/// This is the collection of all data regarding a level, including layout, objects, mobs, and story elements.
///
class Level
{
public:
//Constructor
Level(int height, int width, std::string name);
//For obtaining positional data
int GetHeight();
int GetWidth();
std::string GetName();
sf::Image GetTileImage(int image);
sf::Image GetMobImage(int image);
std::vector< std::vector<Tile> >& GetGrid();
void NewHerder(int x, int y);
void NewBaby(int x, int y);
void GameCycle(sf::RenderWindow* App);
void GraphicsCycle(sf::RenderWindow* App);
private:
//Size
int m_Height;
int m_Width;
//Spatial coords
std::string m_Name;
//The grid of tiles.
std::vector< std::vector<Tile> > m_Grid;
//A vector of the images to be used for tiles.
std::vector<sf::Image> m_TileImages;
//A vector of the images to be used for tiles.
std::vector<sf::Image> m_MobImages;
//The herders
std::vector<Herder> m_Herders;
//The babies
std::vector<Baby> m_Babies;
};
#endif // LEVEL_H_INCLUDED
EDIT: Pre-emptively, here are the contents of Tile.h:
#ifndef TILE_H_INCLUDED
#define TILE_H_INCLUDED
#include <SFML/Graphics.hpp>
#include <cstdlib>
#include "Level.h"
class Level;
/// TILE
/// This is the basic environmental unit in the game
///
class Tile
{
public:
//Constructor
Tile(int col, int row, int size, int type, Level* level);
//For obtaining positional data
int GetX();
int GetY();
int GetRow();
int GetCol();
//For obtaining type data
int GetType();
//For obtaining string type data
std::string GetStringType();
//For changing type data
void SetType(int type);
void SetStringType(std::string character);
//For activities that regularly take place
void GameCycle();
//Draws the tile.
void Draw(sf::RenderWindow* App);
private:
//The level this tile belongs to.
Level* m_Level;
//Size (it's a square!)
int m_Size;
//Spatial coords
int m_X;
int m_Y;
//Grid coords
int m_Row;
int m_Col;
//Type
int m_Type;
//Visual data
sf::Sprite m_Tile;
};
#endif // TILE_H_INCLUDED
It is a cyclic dependency (Herder.h includes Level.h which includes Herder.h, etc.).
In Herder.h, simply replace this :
#include "Level.h"
with :
class Level;
and do the same in Mob.h
The general rule is to include as little header files as possible (ie. only the ones you need). If you can get by with a forward declaration eg., then use that rather than a full include.
The problem you have is a cyclic dependency which is a code smell. On the one side, to be able to derive from a type, the base definition must be available to the compiler (i.e. the compiler requires a fully defined type from which to inherit). On the other hand your base class depends on the derived class.
The technical answer is to forward declare the derived type (so that you can define the base), and then define the base. But you should really think on what you are doing: why are those two separate types related by inheritance? Why not one? Or three (split responsibilities)? If the base depends on the derived for it's own interface, that seems to indicate that they are too highly coupled. Rethink the design.
"Herder.h" and "Level.h" are #include in each other. So, I think this error is coming from the "Herder.h" which is included first. It's becoming cyclic. Remove that and see if the error goes away.

invalid use of incomplete type / forward declaration

I tried to look at the similar problems listed here on Stackoverflow and on Google but they deal mostly with templates and that's not my case. I'm using GCC 4.4.5 on Debian Testing 64bit.
So, I have two classes - CEntity:
#ifndef CENTITY_H_INCLUDED
#define CENTITY_H_INCLUDED
#include "global_includes.h"
// game
#include "CAnimation.h"
#include "Vars.h"
#include "vector2f.h"
#include "Utils.h"
class CAnimation;
class CEntity
{
public:
CEntity();
virtual ~CEntity();
void _update(Uint32 dt);
void updateAnimation(Uint32 dt);
void addAnimation(const std::string& name, CAnimation* anim);
void addAnimation(const std::string& name, const CAnimation& anim);
void removeAnimation(const std::string& name);
void clearAnimations();
bool setAnimation(const std::string& name);
SDL_Surface* getImage() const;
const vector2f& getPos() const;
const vector2f& getLastPos() const;
F getX() const;
F getY() const;
F getLastX() const;
F getLastY() const;
SDL_Rect* getHitbox() const;
SDL_Rect* getRect() const;
F getXSpeed() const;
F getYSpeed() const;
void setPos(const vector2f& pos);
void setPos(F x, F y);
void setPos(F n);
void setX(F x);
void setY(F y);
void setHitboxSize(int w, int h);
void setHitboxSize(SDL_Rect* rect);
void setHitboxWidth(int w);
void setHitboxHeight(int h);
void setSpeed(F xSpeed, F ySpeed);
void setXSpeed(F xSpeed);
void setYSpeed(F ySpeed);
void stop();
void stopX();
void stopY();
void affectByGravity(bool affect);
void translate(const vector2f& offset);
void translate(F x, F y);
bool collide(CEntity& s);
bool collide(CEntity* s);
protected:
CAnimation* mCurrentAnimation;
SDL_Surface* mImage;
vector2f mPos;
vector2f mLastPos;
SDL_Rect* mHitbox; // used for collisions
SDL_Rect* mRect; // used only for blitting
F mXSpeed;
F mYSpeed;
bool mAffByGrav;
int mHOffset;
int mVOffset;
private:
std::map<std::string, CAnimation*> mAnims;
};
#endif // CENTITY_H_INCLUDED
and CPlayerChar which inherits from CEntity:
#ifndef CPLAYERCHAR_H_INCLUDED
#define CPLAYERCHAR_H_INCLUDED
#include "global_includes.h"
// game
#include "CEntity.h"
class CEntity;
class CPlayerChar : public CEntity
{
public:
CPlayerChar();
virtual ~CPlayerChar();
virtual void update(Uint32 dt) = 0;
virtual void runLeft() = 0;
virtual void runRight() = 0;
virtual void stopRunLeft() = 0;
virtual void stopRunRight() = 0;
virtual void attack() = 0;
virtual void stopAttack() = 0;
virtual void attack2() = 0;
virtual void stopAttack2() = 0;
virtual void ground() = 0;
virtual void midair() = 0;
void jump();
void stopJump();
protected:
// looking right?
bool mRight;
bool mJumping;
bool mOnGround;
bool mGrounded;
};
#endif // CPLAYERCHAR_H_INCLUDED
When I try to compile it, GCC throws this error:
CPlayerChar.h:12: error: invalid use of incomplete type ‘struct CEntity’
CPlayerChar.h:9: error: forward declaration of ‘struct CEntity’
I tried it first without the forward declaration 'class CEntity;' in CPlayerChar.h on line 9, but then it would throw this instead
CPlayerChar.h:12: error: expected class-name before ‘{’ token
So the forward declaration has to be there. Also, CEntity is clearly a class, not a struct.
You have a circular inclusion in your header files.
But without all the header files we will not be able to fix it.
I would start here.
#include "CAnimation.h"
Looking at your header you don't actually need this. You only use CAnimation by reference or pointer so the forward declaration you have should be sufficient. Move the include into the source file (ie out of the header).
The next place I would look is:
#include "global_includes.h"
Any global includes that are included in a header file better be very simple. Should only contain simple types and not include any other header files (unless they are just as simple). Anything complex is going to lead to problems with circular dependencies.
General rule of thumb
A header file should only include header files that it absolutely needs. Otherwise they should be included from the source file. You only absolutely need a header file if it defines a class that is used as a parent class you have members objects of that class, or you use parameter objects of that class.
I use the term object to distinguish from references or pointers. If you are using these you do not need to include the header file. You only need to do a forward declaration.
You probably have got a loop in your includes in such way that CPlayerChar doesnt know who really is CEntity, it just knows that it exists, but doesnt know what is it.
If you remove the "class CEntity" declaration, you will see that GCC will complain that CEntity doesnt exists.
You must check that nothing that CEntity includes include CPlayerChar.
You have to ensure that the full definition of the class CEntity is visible at the point where you define the class CPlayerChar. (So check your inclusions.)
This is because you can only inherit from fully defined classes, but not from just forward-declared ones.
The only time you can get away with forward-declarations in place of full definitions is when you make pointers or references to a type, but only if you never access any of its members, or (thanks to #Alf) when declaring a function with incomplete return type.