Jump to content
  • Advertisement
Sign in to follow this  
MightyNinja

[SOLVED] Polymorphism

This topic is 3943 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 all. Well i'm having some problems with polymorphism. Within my main function i'm creating a CEnemy* which contains a CBubble. I'm then trying to access the Initialise function of my new objecct. I want to access the initialise function associated with my CBubble class, but keep getting Initialise for my CEnemy class.
CEnemy* pEnemy = new CBubble();
pEnemy->Initialise(10,0.0f);


I'm sure i'm doing something stupid, but I can't think what :P I've included my header files below. Thanks for any help :) bubble.h
// Local Includes
#include "enemy.h"

// Types

// Constants

// Prototypes

class CBubble : public CEnemy
{
     // Member Functions
public:
	CBubble();
	virtual ~CBubble();

	virtual bool Initialise(int _iStartHp, float _fLifeTime);
	virtual void Process(float _fDeltaTick);
	virtual void Draw();

protected:

private:

     // Member Variables
public:

protected:

private:

};


enemy.h
// Local Includes
#include "entity.h"
// Types

// Constants

// Prototypes

class CEnemy : public CEntity
{
     // Member Functions
public:
	CEnemy();
	virtual ~CEnemy();

	virtual bool Initialise(int _iStartHp, float _fLifeTime, const int _kiSpriteID, const int _kiMaskID, float _fX, float _fY);
	virtual void Process(float _fDeltaTick);
	virtual void Draw();

	void DeductHp(const int _iDeductHp);
	int GetHp();

	bool IsDead();
	bool IsAtPathEnd();

	void SetLifeTime(float _fLifeTime);
	float GetLifeTime();

	void MoveAlongPath();

protected:

private:

     // Member Variables
public:

protected:

private:
	int m_iHp;
	int m_iMoveSpeed;
	//int m_iLifeModifier;
	float m_fLifeTime;
	bool m_bDead;

};


entity.h
// Library Includes

// Local Includes

// Types

// Constants

// Prototypes
class CSprite;

class CEntity
{
     // Member Functions
public:
	CEntity();
	virtual ~CEntity();
	
	virtual bool Initialise(const int _kiSpriteID, const int _kiMaskID);

	virtual void Draw();
	virtual void Process(float _fDeltaTick);

	void SetX(float _fX);
	void SetY(float _fY);
	
	float GetX() const;
	float GetY() const;

	float GetHeight() const;
	float GetWidth() const;

protected:

private:
	CEntity(const CEntity& _kr);
	CEntity& operator= (const CEntity& _kr);

     // Member Variables
public:

protected:
	CSprite* m_pSprite;

	float m_fX;
	float m_fY;

private:

};


[Edited by - MightyNinja on October 27, 2007 8:01:05 PM]

Share this post


Link to post
Share on other sites
Advertisement
I think I understand your problem:

Since you declared pEnemy as a CEnemy*, the compiler will address it as a CEnemy instance. Polymorphism should be taken the other way around: Since every CBubble is a CEneny, but not every CEneny is a CBubble, then you should either declare pEnemy as a CBubble, so as to access the member fuctions associated with that particular class, or leave it as it is, but cast it to CBubble when invoking its initialize function, like this:

CEnemy* pEnemy = new CBubble();
(CBubble)pEnemy->Initialize(10.0f);

I'd recommend you to do it the first way, since you can do

pBubbleEnemy->CEnemyMemberFuction();

but you cannot do

pEnemy->CBubbleMemberFunction();

I hope this helps you out!!! don't forget to rate me!!

Share this post


Link to post
Share on other sites
CEnemy::Initialise and CBubble::Initialise have differing parameters. In order for a function in a derived class to be dynamically called instead of a function in the base class, they must have the same return type, name and parameters.

If you want to keep using the specialised CBubble::Initialise function for CBubbles, you can declare your pointer as a CBubble* when you create the object, so that the Initialise() call statically binds to CBubble::Initialise. This isn't really polymorphism, however. You can then convert it to a CEnemy* for storage in a vector or something, and access it like you would any other CEnemy*.

A better way to deal with this would involve altering your design, but I'm a little too hazy now to think of it, sorry.

Edit: Another look made me aware of something else. CEnemy::Initialise has a bunch of parameters. What this effectively means is that every CEnemy needs those parameters in order to Initialise. As CBubble is also a CEnemy, it should also need those parameters, no? Yet they aren't in the parameter list for CBubble::Initialise. If a CBubble doesn't need all of these parameters, you should rethink whether CBubble should really derive from CEnemy. If it does need them, then use them in CBubble::Initialise!

Share this post


Link to post
Share on other sites
Using a post-construction initialization function instead of a constructor or factory function is often a sign of an incorrect design. This means that your design could be simplified and indirectly eliminate all problems related to initialization. Why do you need that Initialise function?

Share this post


Link to post
Share on other sites
You definately need to change your design, because right now you don't understand very well how object construction or inheritance or polymorphism or overloading works. You should not rush into fleshing out your classes before you have some understanding of the basics. Keep in mind though that, as scjohnno said, inheritance defines an "is-a" relationship. If type B is derived from type A, it means that B is-an A, and it must support all the operations and properties A supports.

And FighterNinja, your remarks were incorrect as well. If the OP's code was correct, then he would be able to call a CBubble method using a CEnemy* pointer. That's the point of polymorphism. I would suggest you avoid advising others before you have the matters cleared up for yourself first.

Share this post


Link to post
Share on other sites
Thanks for the replies. I went back and completely re-wrote my classes removing the initalise function. I do understand the concepts, it's just putting them into a semi-large project which stuffed me up (designing the classes before hand didn't help me hehe).

Anyhoo thanks for the comments, and it's all working now :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Fighterguard
I think I understand your problem:

Since you declared pEnemy as a CEnemy*, the compiler will address it as a CEnemy instance. Polymorphism should be taken the other way around: Since every CBubble is a CEneny, but not every CEneny is a CBubble, then you should either declare pEnemy as a CBubble, so as to access the member fuctions associated with that particular class, or leave it as it is, but cast it to CBubble


Wrong, and completely missing the point of polymorphism, which is specifically to avoid having to make this cast.

Quote:
Original post by scjohnno
CEnemy::Initialise and CBubble::Initialise have differing parameters. In order for a function in a derived class to be dynamically called instead of a function in the base class, they must have the same return type, name and parameters.


Correct, but likely still missing the mark.

Quote:
Original post by ToohrVyk
Using a post-construction initialization function instead of a constructor or factory function is often a sign of an incorrect design. This means that your design could be simplified and indirectly eliminate all problems related to initialization. Why do you need that Initialise function?


Quote:
Original post by mikeman
You definately need to change your design, because right now you don't understand very well how object construction or inheritance or polymorphism or overloading works. You should not rush into fleshing out your classes before you have some understanding of the basics. Keep in mind though that, as scjohnno said, inheritance defines an "is-a" relationship. If type B is derived from type A, it means that B is-an A, and it must support all the operations and properties A supports.


Yep.

In C++, we construct objects using a constructor.

OP: Try reading this.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!