Page 1 of 2

Polymorphic fail

Posted: Sat Jan 17, 2009 8:12 pm
by JS Lemming
So I was trying to be cool and have my stage objects all inherit from a purely virtual object class so I could use one list to hold all my stage objects.

Code: Select all

class stageObject
{
	public:
		stageObjectType type;  //hector, pipe, food, etc.

		stageObject();
		virtual void update()=0;
		virtual void draw()=0;
};
Only problem is I need the stage objects to be able to interact with one another, which requires that, say, the hector class can access the variables in the pipe class. I have a feeling this can't be done the way I got it set up. Unless anyone has some ideas I'll have to have separate lists for all the different kinds of stage objects and that's kinda lame.

Re: Polymorphic fail

Posted: Sat Jan 17, 2009 8:26 pm
by M_D_K

Code: Select all

      virtual void update()=0;
      virtual void draw()=0;
when you do that you'll get compile errors since its purely virtual. You need to do this

Code: Select all

      virtual void update() {};
      virtual void draw() {};
that will make it compile just never use stageObject directly just use so that you can pass anything based off it.

Re: Polymorphic fail

Posted: Sat Jan 17, 2009 8:45 pm
by JS Lemming
Umm I can compile just fine. There's nothing wrong with my code. Maybe reread my question and if you still aren't clear on what I'm asking I'll try to be more precise.

Re: Polymorphic fail

Posted: Sat Jan 17, 2009 8:55 pm
by Ginto8
I think he meant that if you make an object of the base class and try to use those functions it won't work.
If you only make instances of the derived classes, it will be fine using them so long as they have been overloaded.

Re: Polymorphic fail

Posted: Sat Jan 17, 2009 9:29 pm
by JS Lemming
Yeah, I know all that stuff. My program works just fine. My problem, which isn't really a problem so much as poor design, is that I can't access values in the derived classes from within a different derived class. I'm asking if there is some sly way of overcoming that, which I doubt but was unsure of, and if not I will simply not utilize polymorphism and instead make separate lists containing the separate stage objects which I know for a fact I can access the variables from.

Sorry for the confusion.

Re: Polymorphic fail

Posted: Sat Jan 17, 2009 9:35 pm
by M_D_K
you could store everything in one list and create a temp class to access everything..

Code: Select all

[...]
if(m_objects[i]->type == pipe)
{
    Pipe pipe = &m_objects[i];
    hector->SetSomeFunc(pipe.derivedOnlyFunc());
}
I guess... Its late here so I may be totally wrong...on everything.

Re: Polymorphic fail

Posted: Sat Jan 17, 2009 10:26 pm
by MarauderIIC
JS Lemming wrote:Yeah, I know all that stuff. My program works just fine. My problem, which isn't really a problem so much as poor design, is that I can't access values in the derived classes from within a different derived class. I'm asking if there is some sly way of overcoming that, which I doubt but was unsure of, and if not I will simply not utilize polymorphism and instead make separate lists containing the separate stage objects which I know for a fact I can access the variables from.

Sorry for the confusion.
So you have
Class A
Class B : public A { int qqq; }
Class C : public A { int getqqq() { return qqq;} }

?

No, you can't do that, I don't think. Put qqq in A, then it should work.

Re: Polymorphic fail

Posted: Sat Jan 17, 2009 11:13 pm
by JS Lemming
MarauderIIC wrote:So you have
Class A
Class B : public A { int qqq; }
Class C : public A { int getqqq() { return qqq;} }
Yeah, I'm pretty sure it's not gonna work for me. It's not that big of a deal though. The code will just be a bit more cluttered and harder to maintain with all the separate lists.

Re: Polymorphic fail

Posted: Sun Jan 18, 2009 12:08 am
by MarauderIIC
What I wrote is what you CAN'T do (and what it seems like youre asking to be able to do).

Why not do:

class A { int qqq; }
class B : public A { getqqq() };
class C : public A { getqqq2() };

or
class A { int qqq; getqqq() };
class B : public A... class C : public A

Re: Polymorphic fail

Posted: Sun Jan 18, 2009 12:26 am
by JS Lemming
Because a lot of the derived classes have variables completely unrelated to the variables of others and yet I still need access to them. It defeats the purpose.

Re: Polymorphic fail

Posted: Sun Jan 18, 2009 4:07 am
by MarauderIIC
Perhaps your base class is too abstract. Perhaps you should derive again? Sounds like a design flaw.

class Stuff
class Actor
class NPC
class Player
class Levels

And perhaps you have
class Stuff
class NPC
class Player
class Levels

for instance? (NPC and Player have x,y coords but Levels don't)
Post a class diagram or layout...? I'd like to give you a hand, but I don't really have enough information and it sounds like your problem is solvable...

Re: Polymorphic fail

Posted: Sun Jan 18, 2009 8:10 am
by Ginto8
If you're talking about accessing private variables from other classes, here's what you could do: make an overloaded function that is a friend of all the classes.

example:

Code: Select all

class A // placeholder class #1
{
    int a;
    public:
        friend inline int get_a( A object );
};

class B // placeholder class #2
{
    int a;
    public:
        friend inline int get_a( B object );
};

inline int get_a( A object ) // get_a for class A
{
    return object.a;
}

inline int get_a( B object ) // get_a for class B
{
    return object.a;
}
this would give you access to private members, but here's a better idea using friend classes:

Code: Select all

class A
{
    int a;
    friend class B;
};

class B
{
    A object; // B can manipulate object's private members because of the friend class declaration
    public:
       B();
       int get_a();
};

B::B( int a )
{
    object.a = a;
}

int B::get_a()
{
    return object.a;
}
or is that not what you're looking for?

Re: Polymorphic fail

Posted: Sun Jan 18, 2009 9:56 am
by qpHalcy0n
You could simply map out the things that the child objects have in common with eachother and store them as protected members of the base class.

Re: Polymorphic fail

Posted: Sun Jan 18, 2009 12:40 pm
by JS Lemming
qpHalcy0n wrote:You could simply map out the things that the child objects have in common with eachother and store them as protected members of the base class.
I know, but it would be a lot of stuff. Not practical and hard to maintain.

I think some of you still don't know what I'm trying to say so maybe this will help.
Base class:

Code: Select all

#ifndef STAGEOBJECT_H
#define STAGEOBJECT_H

#include "enum.h"

class stageObject
{
	public:
		stageObjectType type;

		stageObject();
		virtual void update()=0;
		virtual void draw()=0;
		
		//for objects like hector who need to report it's x position so the proper
		// baseX can be set...
		virtual float specialReport()=0;
};

#endif // STAGEOBJECT_H
Ignore the specialReport crap. It was my first attempt to fix this problem and I didn't think it through. (I need more than one variable to report)

Next, for example, hector class:

Code: Select all

#ifndef HECTOR_H
#define HECTOR_H


#include "stageobject.h"

class hector: public stageObject
{
	public:
		float x, y;
	
		hector(int xStart, int yStart);
		virtual ~hector();
		void update();
		void draw();
		float specialReport();
};

#endif // HECTOR_H
Obviously these classes are in their early stages of development so they don't have many variables and such.

Now say pipe class (actually called gyroPipe since pipe is already taken by C++)

Code: Select all

#ifndef gyroPipe_H
#define gyroPipe_H

#include "stageobject.h"

class gyroPipe: public stageObject
{
	public:
		int imageData;
		int color; //0=blue, 1=red
		bool vertical;
		int startPositive; // 0=no, 1=yes
		int sliderX, sliderY, length;
		float extension;
	
		gyroPipe(int argColor, bool argVertical, int argX, int argY, int argLength, int argImageData);
		virtual ~gyroPipe();
		void update();
		void draw();
		float specialReport();
};

#endif // gyroPipe_H
and so on...

Now I have a list of stageObjects in my code and I run through them to call update() and draw(). My problem is that in order to update some objects, I need to know about (have access to variables from) the other stageObjects so I can perform collisions and whatnot. See what I'm saying? I can only call update() or draw(). I can't get at the variables.

Re: Polymorphic fail

Posted: Sun Jan 18, 2009 12:57 pm
by M_D_K
just make a collision loop inside the update. You get hectors index then check against all objects that hector can collide with(so everything?)

Code: Select all

[...]
for(int i = 0; i < m_objects.size(); i++)
    if(m_objects[i]->type == HECTOR)
    {
        hectorIdx = i;
        break;
    }

for(int i = 0; i < m_objects.size(); i++)
{
    if(m_objects[i]->type != HECTOR)
    {
        if(CheckCollide(m_objects[hectorIdx], m_objects[i]) == true)
            //do stuff
    }
}
So when you do your stageObjectManger::Update() you can run that for collisions and stuff. I'm just spit balling mind you...