Class Dependency issues (C++)

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
ajtgarber
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 97
Joined: Wed Jun 10, 2009 8:56 am

Class Dependency issues (C++)

Post by ajtgarber »

Language: C++
Compiler: GCC 4.4

I have a class NPC that contains an NPCBehavior* instance, the NPCBehavior class has a method update(NPC* npc). Both the classes are dependent on each other. I also have a DefaultNPCBehavior class that is used by the NPC class inside the constructor to give a default behavior to itself. DefaultNPCBehavior extends NPCBehavior. gcc is giving me the following message:
In file included from NPC.h:10,
from NPCBehavior.h:7:
DefaultNPCBehavior.h:10: error: expected class-name before ‘{’ token
NPC.h

Code: Select all

#ifndef NPC_H
#define NPC_H

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <iostream>
#include "Entity.h"
#include "AnimatedEntity.h"
#include "NPCBehavior.h"
#include "DefaultNPCBehavior.h"

class NPCBehavior;
class DefaultNPCBehavior;

class NPC : public AnimatedEntity {
	private:
		int mapShiftX, mapShiftY;
		NPCBehavior* behavior;
	public:
		NPC(SDL_Surface* surface, int x, int y, int width, int height);
		~NPC();

		int getMapShiftX();
		int getMapShiftY();
		void setMapShiftX(int mapShiftX);
		void setMapShiftY(int mapShiftY);

		void setNPCBehavior(NPCBehavior* behavior);

		void update(); //inherited from Entity, AnimatedEntity
		void render(SDL_Surface* screen); //inherited from Entity, AnimatedEntity
};

#endif
NPC.cpp

Code: Select all

#include "NPC.h"

using namespace std;

NPC::NPC(SDL_Surface* sheet, int x, int y, int width, int height) : AnimatedEntity(sheet, x, y, width, height), mapShiftX(0), mapShiftY(0) {
	behavior = new DefaultNPCBehavior();
	cout << behavior << endl;
}
NPC::~NPC() {
	//possible memory leak with behavior (WARNING)
}

void NPC::setNPCBehavior(NPCBehavior* behavior) {
	delete this->behavior;
	this->behavior = behavior;
}

int NPC::getMapShiftX() {
	return mapShiftX;
}
int NPC::getMapShiftY() {
	return mapShiftY;
}
void NPC::setMapShiftX(int mapShiftX) {
	this->mapShiftX = mapShiftX;
}
void NPC::setMapShiftY(int mapShiftY) {
	this->mapShiftY = mapShiftY;
}

void NPC::update() {
	AnimatedEntity::update();
	setX(getX()+getXVel());
	setY(getY()+getYVel());
	behavior->update(this);
}
//extremely similar to AnimatedEntity::render with the change being with the offset rectangle
void NPC::render(SDL_Surface* screen) {
	SDL_Rect offset;
	offset.x = getX()+mapShiftX;
	offset.y = getY()+mapShiftY;

	SDL_Rect clip;
	clip.x = getFrameNum()*getWidth();
	clip.y = getDirection()*getHeight();
	clip.w = getWidth();
	clip.h = getHeight();

	SDL_BlitSurface(getSheet(), &clip, screen, &offset);
}
NPCBehavior.h

Code: Select all

#ifndef NPCBEHAVIOR_H
#define NPCBEHAVIOR_H

#include <iostream>


#include "NPC.h"
#include "Entity.h"

class NPC;

class NPCBehavior {
	public:
		NPCBehavior();

		virtual void update(NPC* npc) = 0;
};

#endif
NPCBehavior.cpp

Code: Select all

#include "NPCBehavior.h"

NPCBehavior::NPCBehavior() {
	
}
DefaultNPCBehavior.h

Code: Select all

#ifndef DEFAULTNPCBEHAVIOR_H
#define DEFAULTNPCBEHAVIOR_H

#include "Entity.h"
#include "NPCBehavior.h"
#include "NPC.h"

class NPC;

class DefaultNPCBehavior : public NPCBehavior {
	private:
		int counter;
	public:
		DefaultNPCBehavior();

		void update(NPC* npc);
};

#endif
DefaultNPCBehavior.cpp

Code: Select all

#include "DefaultNPCBehavior.h"

DefaultNPCBehavior::DefaultNPCBehavior() : counter(0) {

}

void DefaultNPCBehavior::update(NPC* npc) {
	if(npc->getXVel() == 0) npc->setXVel(4);
	counter++;
	if(counter == (60*4)) {
		counter = 0;
		npc->setXVel(-npc->getXVel());
	}
}
User avatar
bnpph
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 75
Joined: Thu Mar 10, 2011 12:30 pm

Re: Class Dependency issues (C++)

Post by bnpph »

It might be from DefaultNPCBehavior.h because you didn't forward declare class NPCBehavior.

Also, if you only need pointers in h file, then you can only include in the .cpp
like this:

bar.h

Code: Select all

#pragma once
class bar {
public:
  int var;
  bar();
  ~bar();
};
(pretend bar.cpp exists and implements everything)

foo.h

Code: Select all

#pragma once
class bar;
class foo {
  foo();
  ~foo();
  bar* m_bar;
};
foo.cpp

Code: Select all

#include "foo.h"
#include "bar.h"

foo::foo() {
  m_bar = new bar[4];
}

foo::~foo() {
  delete[] m_bar;
}

This gets rid of circular dependency, improves compile time, and is "proper" way to do so.
ajtgarber
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 97
Joined: Wed Jun 10, 2009 8:56 am

Re: Class Dependency issues (C++)

Post by ajtgarber »

If I compile it with the forward declaration of NPCBehavior in DefaultNPCBehavior I get these error messages:
In file included from NPC.h:10,
from NPCBehavior.h:7:
DefaultNPCBehavior.h:11: error: invalid use of incomplete type ‘struct NPCBehavior’
DefaultNPCBehavior.h:9: error: forward declaration of ‘struct NPCBehavior’
ajtgarber
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 97
Joined: Wed Jun 10, 2009 8:56 am

Re: Class Dependency issues (C++)

Post by ajtgarber »

While I do see how that foo, bar class implementation gets rid of circular dependencies, I guess I don't really see how I can still implement what I need to with this.
The NPC object needs to have a way to call update on an NPCBehavior object. and the NPCBehavior object needs some way to tell what its updating so it can call
methods such as setXVel or something of that sort.

If I'm being an idiot feel free to tell me so.

I know I can use an Entity* instead of using an NPC* inside the NPCBehavior class, but if I don't have to I'd prefer not to, since the NPCBehavior class is meant to work on NPC's rather than generic entities.
User avatar
MrDeathNote
ES Beta Backer
ES Beta Backer
Posts: 594
Joined: Sun Oct 11, 2009 9:57 am
Current Project: cocos2d-x project
Favorite Gaming Platforms: SNES, Sega Megadrive, XBox 360
Programming Language of Choice: C/++
Location: Belfast, Ireland
Contact:

Re: Class Dependency issues (C++)

Post by MrDeathNote »

In NPC.h your including AND forward declaring NPCBehavior.h and DefaultNPCBehavior.h. Remove the includes and put them in NPC.cpp. Also you cannot forward declare NPCBehavior in DefaultNPCBehavior.
http://www.youtube.com/user/MrDeathNote1988

Image
Image

"C makes it easy to shoot yourself in the foot. C++ makes it
harder, but when you do, it blows away your whole leg." - Bjarne Stroustrup
Post Reply