Archived

This topic is now archived and is closed to further replies.

flamewill

C++ Class Declaration Catch 22?

Recommended Posts

Hi, I'm one of those learning C++ and trying to program an RPG with it. There is a problem that has been bugging me for ages. To illustrate, consider two classes: Class Creature { Spell* spellbook[10]; void addSpell(Spell*); }; Class Spell{ Creature* pCaster; void setCaster(Creature*); void cast(); }; The aim is to have the Creature contain its spells. At the same time, each spell knows its owner/caster so it can determine who to target (& other effects). A similar approach is intended for armors, weapons etc. I can get around this by declaring Spell first and implement its class after Creature. However, I get this gut feeling that situations like this should be avoided and a better design is the real solution. Would someone please give me some suggestions/comments, or point me to the right website? Thanks in advance. [edited by - flamewill on March 3, 2003 8:17:52 AM] [edited by - flamewill on March 3, 2003 8:19:56 AM]

Share this post


Link to post
Share on other sites
You can add

class Spell;

before
class Creature
{
...
}


this works ok, as long as it is only pointers

Share this post


Link to post
Share on other sites
In the header/declaration you can use a forward declaration:


  
// Spell.h

class Creature;

class Spell {
void setCaster(Creature *);
};



// Creature.h

class Spell;

class Creature {
void addSpell(Spell*);
};


Provided you don''t use any functions or member variables of Spell in the Creature header, or Creature in the Spell header. If you do you''ll get complains about using an undefined class. In the source/definition you include the appropriate header file so you don''t have those problems.


  
// Spell.cpp


// without this line the compiler will complain about using

// the undefined class Creature on the c->addSpell line

#include "Creature.h"

void Spell::setCaster(Creature * c) {
c->addSpell(this);
}


// Creature.cpp


// likewise without this line the compiler will say you''re using

// the undefined class Spell on the s->setCaster line

#include "Spell.h"

void Create::addSpell(Spell * s) {
s->setCaster(this);
}

Share this post


Link to post
Share on other sites
Thanks for all the replies (though I''m not sure how to use references to solve the problem, merlin9x9). I''ve used forward declaration before, but am reluctant to put up with a potently lengthy list of these class declarations. Fortunately, a solution popped into my head half a day after I posted this question!

I realised my bottom line is to let the Spell class know who its caster is. This way a Spell knows who to heal, or who the enemy is (for magic missiles etc).

Moreover, because I am making a turn based game, there should only be one Creature active at any one time. Extending this assumption, the Spell can only be cast from the active Creature. So if I stick to this rule, the following can be declared in the order shown:

class Spell {
void cast();
};

class Creature {
Spell* spellbook[10];

void takeDamage(int d);
};

class World {
Creature* combatants[10];
...

Creature* getActive();
};

To elaborate a bit more, the World class contains all the creatures and other entities in the game world. There will be a global World object, from which all other classes can search.

Thereafter, the code of void Spell::cast() can request World for the currently active combatant, who must be the caster! Just tested this methodology out, and everything seems to work fine!

Any comments, or am I not making sense?

Share this post


Link to post
Share on other sites
merlin9x9''s reply was just a note on my reply, like:

"this works ok, as long as it is only pointers"
"...or references." (which is just pointers in disguise =)

Share this post


Link to post
Share on other sites