Jump to content
  • Advertisement

Archived

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

graveyard filla

how do i call a base class's constructer using derived pointers??

This topic is 5280 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

high, im working on a top down 2d rpg/shooter. right now im working on combat and trying to add more types of weapons. right now im adding a flamethrower weapon, anyway, heres the problem: i have a base class called Projectiles. now, this class does the majority of the work for every type of projectile. i have 2 classes which derive from Projectiles - class Bullets, and class Flames.... the ONLY differenece between a Bullet and a Flame is the width,height, and texture. That, and how they Render()... anyway, so i make Render() virtual from inside of Projectiles... then, i initialize the texture/width/height from inside of Bullets and Flame (since those 3 are different from each other in the different children..) now heres the problem : i have a class called Weapons, which has a member list < Projectiles* > bullets; when a weapon is Fired(), i calculate the projectiles dx,dy, and send it some other data. BEFORE i had multiple types of bullets and i just had a list of < bullets >, it looked like this: bullets.push_back(Bullets(tempx,tempy,dest_x,dest_y,parent,current_target,range)) now, this big ass constructor is the constructor to my Projectiles class. how do i go about doing this:

		if(type == SMG || type == PISTOL)
		{
			Bullets *temp = new Bullets( I WANT MY DATA HERE!!!);	
			bullets.push_back(temp);
			//bullets.push_back(Projectiles(tempx,tempy,dest_x,dest_y,parent,current_target,range));

		}
		else if (type == FLAMETHROWER
		{
			Flame *temp = new Flame( I WANT MY DATA HERE!!!);
			bullets.push_back(temp);
		}

do you see what im trying to do? im trying to add a flame / bullet to my list of projectiles, depending on what kind of weapon i am... but how do i do this? i could easily just make the constructor of the bullets/flames class receive that data, but that would be ugly duplication.. how do i go about calling the base constructor when i new a derived object? heres what my classes implementation looks like:
class Projectiles: public Entity
{

	public:

		Projectiles(float x, float y,float dest_x, float dest_y,Character *parent,Character *current_target,int range);
		virtual ~Projectiles();

		bool Update();
		virtual void Render() = 0;

		bool Bullet_Collide(Character *target); 


	protected:

		bool Wall_Collision(int x, int y, int &tilecoordx);			//tests for collision with a tile on the vertikal line from [x,y] to [x,y+height]


		Character *current_target;
		Character *parent;

		float dx;
		float dy;

		float start_x;
		float start_y;

		int range;

		GLuint texture;
	
};

class Bullets : public Projectiles
{
	public:
	
	Bullets();
	~Bullets(){};

	virtual void Render();

};

class Flame : public Projectiles
{
	public:
		
		Flame();
		~Flame(){}

		virtual void Render();

};
thanks for any help!!! [edited by - graveyard filla on May 31, 2004 10:47:27 PM] [edited by - graveyard filla on May 31, 2004 10:53:50 PM]

Share this post


Link to post
Share on other sites
Advertisement
thanks, but that doesnt really help. for one thing, their base class and derived class both recieve a variable with the same name, which confuses the hell out of me. not to mention they dont give an example. could someone please enlighten me? thanks

Share this post


Link to post
Share on other sites
Yes, there''s an example. Albeit maybe not the best example, but it''s MSDN, what do you expect?

Basically, let''s say you have base class Base, and derived class Derived. Your derived constructor looks like this:

Derived::Derived(/* optional parameters */) : Base(/* optional parameters */)
{
...
}

Basically, you call the base class constructor from an initialization list attached to the derived constructor. You can call any of the base constructors, but if it takes parameters, you have to provide them. Usually, if a base constructor needs a parameter, you pass it to the derived class constructor, and then pass it to the base class constructor:

Derived::Derived(int intBaseClassNeeds) : Base(intBaseClassNeeds)
{
...
}

Share this post


Link to post
Share on other sites
  
class Projectiles: public Entity
{

public:

Projectiles(float x, float y,float dest_x, float dest_y,Character *parent,Character *current_target,int range);
virtual ~Projectiles();
//etc, etc....

};

class Bullets : public Projectiles
{
public:
Bullets(float x, float y,float dest_x, float dest_y,Character *parent,Character *current_target,int range);
//etc, etc...

};

Bullets::Bullets(float x, float y,float dest_x, float dest_y,Character *parent,Character *current_target,int range) : Projectiles (x, y, dest_x, dest_y, parent, current_target, range)
{
// Bullet-specific stuff here

}

Share this post


Link to post
Share on other sites
Whats so confusing about that?

they gave enough of an example:
// spec1_initializing_base_classes.cpp

// Declare class Window.

class MyClass
{
public:
MyClass( int rSize )
{
}
};

// Declare class DialogBox, derived from class MyClass

class DialogBox : public MyClass
{
public:
DialogBox( int rSize );
};

// Define the constructor for DialogBox. This constructor

// explicitly initializes the MyClass subobject.

DialogBox::DialogBox( int rSize ) : MyClass( rSize )
{
}


or are you confused because they didnt sperate it into a .h and .cpp file?

Anyway, the key is this line right here:
DialogBox::DialogBox( int rSize ) : MyClass( rSize )

this would also work
DialogBox::DialogBox( int rSize ) : MyClass()
providing MyClass had a default constructor.

PS:
"both recieve a variable with the same name, which confuses the hell out of me"
then just make your code do that too, then try to change the names and see what happens. (hit, you wont notice a difference).

Share this post


Link to post
Share on other sites
Suggestions: 1. Methinks the member variable of your Weapons class called bullets should be called projectiles. Its confusing now because it looks like the Bullets class which derives from Projectiles when really its a pointer to a Projectiles. 2. I think you should also stop pluralizing your class names since each instance of the class is a singular, not a multiple. Or if its meant to represent a stream of projectiles, call it ProjectileStream.

I would make a constructor in both the Bullets and Flames classes that takes whatever you need. Then have the constructor call the constructor of the base class, passing the data along. Sure its duplication, but constructors shouldn't need to be changed very often for a well-thought-out set of classes.


class Projectile : public Entity
{
public:
Projectile(unsigned int x, unsigned int y) :
_x(x),
_y(y)
{
}

private:
unsigned int _x;
unsigned int _y;
};

class Bullet : public Projectile
{
public:
Bullet(unsigned int x, unsigned int y) :
Projectile(x, y)
{
}
};


Forgive me if I misunderstood your question, but its late.

[edited by - dcosborn on May 31, 2004 12:29:56 AM]

Share this post


Link to post
Share on other sites
The easiest way to implement virtual constructors is to have a base-class with A pointer to itself inside of it. You''ll also need a protected dummy constructor. Take a look at the code...


class BaseClass
{
private:
// pointer to this class
BaseClass *realClass;

protected:

BaseClass(struct_you_wont_use param) // this is needed to stop recursive instantiation
{
}

///////////////////

public:

BaseClass(int param)// this is the real constructor
{
if(params.weapon == GUN)realClass = new Gun();
if(params.weapon == FLAME)realClass = new Flames();
}

virtual void foo(){realClass->foo();}
virtual void foo2(int i){realClass->foo2(i);}
};

// gun class
class Gun : public BaseClass
{
public:
Gun():BaseClass(struct_you_wont_use)
{
// init stuff
}
}

// Flames class
class Flame : public BaseClass
{
public:
Flame():BaseClass(struct_you_wont_use)
{
// init stuff
}
}



Basicly, you are initializing two instances of the base class, one instance parses the data, and the other instance handles normal OOP implementations. Note that you''ve got to call realClass->foo() to get the implementation, and that all your functions should be virtual.

Share this post


Link to post
Share on other sites
edit: i solved the problem, for some screwed up reason the files were never even part of my project!!!

but id like to know how this all works exactly, and just want to confirm.

when i do this:

Derived::Derived(int blah): Base (blah)

this says "when i call the derived constructor, ill recieve the parameters, and then call the base constructor and send those parameters to it"

is this correct? also, what i dont understand is, when you create a derived class, doesnt it call the base class''s constructor first? if so, then how does it call base const., call derived constr, and then call base constr again? thanks for any further help...

Share this post


Link to post
Share on other sites
is this correct?

That''s the idea, yes.

also, what i dont understand is, when you create a derived class, doesnt it call the base class''s constructor first?

Yes.

if so, then how does it call base const., call derived constr, and then call base constr again?

It''s more like nested function calls. The compiler (statically) analyses the initializer list in each constructor to find out which parameters must be ''passed down'' to the base constructors. The base classes are initialized first, followed by the derived classes, in order.

Note that virtual base classes make the issue a tad more complicated, since only the most derived class does the virtual base initialization (i.e. if you create a Base object, Base is the most derived class, but if you create a Derived object, Derived is the most derived class - the actual class of the object).

A "constructor call" basically boils down to:
- (If most derived, initialize virtual bases (init list))
- Initialize base classes (init list)
- Initialize member variables (init list)
- Execute code block.

Share this post


Link to post
Share on other sites

  • 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!