• Advertisement

Archived

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

C++ Question

This topic is 6218 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everybody, I have a base class Character. Classes Soldier and Monster inherit it. I store objects of Soldier and Monster in an array Character *ary[10]. My question is, how to access the data and functions of Soldier and Monster objcets using the Character pointer? Thank you very much. Frank

Share this post


Link to post
Share on other sites
Advertisement
I hope I''m understanding you right on this. To access a data structure or class from a pointer, use -> instead of a period:

class cMyClass
{
public:
DWORD dwVar;
};

cMyClass *Mine;

Mine = new cMyClass();
Mine->dwVar = 10;
delete Mine;

All derived classes use the base class data as well:

class cMyDerivedClass : public cMyClass
{
public:
DWORD dwVar2;
};

cMyDerivedClass *Mine;

Mine = new cMyDerivedClass();
Mine->dwVar = 10;
Mine->dwVar2 = 10;
delete Mine;

Jim Adams

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Correct me if I''m wrong.. but this is polymorphism right?

Class character has to have virtual functions like

virtual takeDamage(int damage);


then both Soldier and Monster can have their specific takeDamage()

then when you call character->takeDamage, the proper takeDamage() is called depending on wether or not the Character pointer is pointing to type monster or soldier. If either Monster or Soldier doesn''t have its own takeDamage() function, then the generic character::takeDamage() is called.

Right?

Share this post


Link to post
Share on other sites
Hi Jim Adams,

Sorry for my poor English...what I mean is, in your example, use "cMyClass *Mine;" instead of "cMyDerivedClass *Mine;". If I code this, the compiler will complain that cMyClass doesn''t have member dwVar2.

Thanks for your attention.

Frank

Share this post


Link to post
Share on other sites
Try this:

http://www.zib.de/Visual/people/mueller/Course/Tutorial/node7.html

Share this post


Link to post
Share on other sites
  
Character* character = new Soldier[10];
character[0].whateverAttributesSoldierHas = x;
character[0].whateverFunctionsSoldierHas();

Character* other = new Monster[10];
other[0].whateverAttributesMonsterHas = x;
other[0].whateverFunctionsMonsterHas();



"Now go away or I shall taunt you a second time"
- Monty Python and the Holy Grail

Share this post


Link to post
Share on other sites
quote:
Original post by frank2000

Hi everybody,

I have a base class Character. Classes Soldier and Monster inherit it. I store objects of Soldier and Monster in an array Character *ary[10].

My question is, how to access the data and functions of Soldier and Monster objcets using the Character pointer?

Thank you very much.

Frank




You can't access the data and functions of Soldier and Monster object using a Character pointer. The Character class doesn't _know_ anything about Soldiers or Monsters.

You can, however, convert the Character pointer into a pointer to a Soldier or a Monster object.

You should be able to use a C style cast:
Monster *pBadGuy = (Monster *) ary[0];

Or you could use the C++ style cast:
Monster *pBadGuy = static_cast < Monster * > (ary[0]);

And then you could access all of the data and functions of the Monster object through this pointer.

Remember that by doing this, you are bypassing C++'s type checking and you open yourself up for problems. If you convert ary[0] into a Monster pointer, but it really is a Soldier pointer, and then you start calling Monster functions or accessing Monster data, the behavior is undefined, which usually means that your program will crash.

You might want to think about using virtual functions.


Edited by - ShawnO on February 15, 2001 1:49:26 PM

Share this post


Link to post
Share on other sites
Hi ncsu121978,

Thanks for your reply. But it has the same result - the compiler complains that Character doesn''t have the corresponding attributes and functions.

If I use ((Soldier *)Character[0]).whateverAttributesSoldierHas = x; The compiler will shut up. But how can I know that the pointer is currently pointing to Soldier or Monster, so that I can cast the pointer correctly?

My program is a real-time 3d game. It cannot affort comparisons before every assignments or function calls. And the worst thing is I discovered this problem when I''ve finished coding over 70% (because Smalltalk don''t has such problem so I assume that c++ is the same...and start coding). Does anyone know what should I do?

Share this post


Link to post
Share on other sites
Take the data members that are common to both Soldier and Monster into Character instead. Then make the derived classes use the base class''s data members.

For example:



class Character
{
public:
// common stuff:
int HP;
int AmmoRemaining;
};

class Soldier : public Character
{
};

class Enemy : public Character
{
};

void Function(Character* p)
{
// Works for both soldiers and enemies
p->HP = 10;
p->Ammo = 10;
}

int main(int argc, char* argv[])
{
Soldier s1, s2, s3;
Function(&s1);
Function(&s2);
Function(&s3);

Enemy e1, e2, e3;
Function(&e1);
Function(&e2);
Function(&e3);
}

Share this post


Link to post
Share on other sites
Somewhat longwinded, but here''s the basic idea

  
//CCharacter Types

static int CHAR_TYPE = 0;
static int SOLD_TYPE = 1;
static int MONS_TYPE = 2;

//BASE Class

class CCharacter
{
public:
int m_nType;
CCharacter(int nType) : m_nType(nType){}
};

//Soldier child class

class CSoldier : public CCharacter
{
public:
CSoldier() : CCharacter(SOLD_TYPE){}
void Attack(){
printf("FREEZE! I AM A SOLDIER! I K33L J00 NOW!\n");
}
};

//Monster child class

class CMonster : public CCharacter
{
public:
CMonster() : CCharacter(MONS_TYPE){}
void Growl(){
printf("RAR! I AM A MONSTER! PREPARE TO DIE!\n");
}
};

//Growl if pChar is a Monster

bool Growl(CCharacter *pChar){
if(pChar->m_nType == MONS_TYPE){
CMonster *pMons = (CMonster*)pChar;
pMons->Growl();
return true;
}
return false;
}

//Attack if pChar is a Soldier

bool Attack(CCharacter *pChar){
if(pChar->m_nType == SOLD_TYPE){
CSoldier *pSold = (CSoldier *)pChar;
pSold->Attack();
return true;
}
return false;
}

int main(int argc, char* argv[])
{
CMonster m;
CSoldier s;

Attack(&m);
Attack(&s);
Growl(&m);
Growl(&s);

return 0;
}

Share this post


Link to post
Share on other sites
Thanks JonStelly. Your idea can address the problem, but for my program, this would result in hundreds or even thousands of comparisons in every frame. Anyway, thanks for your help.

Thanks you all. I think I would move all the public attributes of Soldier and Monster back to Character, and use virtual functions. This may be the easiest way to corrert my program.

Share this post


Link to post
Share on other sites
Ok, I think I understand what you mean (I think ) BTW - you can access base class information from a derived class, but not the other way. You''ll want to use virtual functions to override functions:

class cBaseChar
{
public:
virtual void Attack() { cout << "ATTACK!"; }
};

class cHero : public cBaseChar
{
private:
long MySpecialData;
};

class cMonster : public cBaseChar
{
public:
void Attack() { cout << "GRRR!"; }
};

main()
{
cHero Hero;
cMonster Monster;

Hero.Attack();
Monster.Attack();
}


Jim Adams
Author "Programming Role-Playing Games with DirectX"
jimadams@att.net

Share this post


Link to post
Share on other sites

  • Advertisement