Inheritance and base class pointers

Started by
6 comments, last by Captain P 13 years, 8 months ago
Hello,

Lets say I have three classes.
class A{public:string name;};class B : public A{public:int sortval;};class C : public A{public:int sortval;};


I want to be able to sort B and C together
This is impossible to do in an array since arrays must only contain one datatype. My thought was to use a base class pointer.

So I did this:

B bclass;C cclass;A* pointerToA[2];pointerToA[0] = &bclass;pointerToA[1] = &cclass;cout << pointerToA[0]->sortval; //This doesn't work


After a bit of reading I discovered that the base class pointer to an inherited class cannot access members of the inherited class.

So, how else could I implement something like this?

My original idea before this was to use

struct sortstruct{B b;C c;}sortstruct[100];

then did the sorting by filling each sortstruct with only either b OR c;
This felt sloppy to me so...

Help me out :)
Advertisement
I don't know how your actual design looks like but the most simple solution would be to include sortval in your base class (this is probably where you are looking for).
class A{public:string Name;int Sortval;// You could also make a virtual set and get methods:virtual int getSortval() {return Sortval;}virtual void setSortval(int sortval) {Sortval = sortval;}};class B : public A{public:};class C : public A{public:};A* Test = new C;std::cout << Test->Sortval << '\n';

I hope this solution fits in your design (but if you want to sort your container every value needs to contain a sortval, so probably yes).

Another solution (which is I think more complicated than necessary) is to create a struct which holds a sortval and a pointer to the base class, like this:
struct Value // or a class doesn't matter{ int Sortval; A* Pointer;};Value First = {1, new B};Value Second = {2, new C};


But I would definitely prefer the first solution.
You're trying to treat B's and C's in the same way. For that purpose, you'll want to give them a common interface. But, they already have a common interface: A's interface. So why not move sortval into A, since apparently every A needs a sortval anyway? Alternately, you could give A a virtual sortval() method, with B and C providing implementations of their own, if you need that kind of flexibility.

That, or you could create a separate Sortable interface (which, in C++, would be done by creating an abstract base class), and have both B and C implement it (derive from it).
Create-ivity - a game development blog Mouseover for more information.
Tell us what you are really doing. Using generic pseudo code is often counter productive when asking questions, as it hinders understanding of what is the goal.

Obviously you may want to simplify so we're not shoulder deep in your implementation details, but a good overview of the problem is essential to a good answer in cases like these.
What I am really trying to do is a combat system for a turn based game.

The problem I am having is that I have a class for Friendly (players units)
and Enemy (npcs). These are derived from Unit (base class).

I want to be able to throw these into an array and sort them by a speed (part of unit).

After they are sorted, the person at slot 0 in the array will "take his turn" and then the list will be resorted.

If I use the unit* as the array type, the problem comes when they need to "take a turn". I don't know how to determine if the current unit in array[0] is a friendly or enemy as they take turns differently.

I did learn that I can do

((derived*)pointerToBase)->memberOfDerived; //legal

But I wouldn't know whether to put enemy or friendly as the cast type, besides this seeming to be a poor implementation.

These types of problems, like rip-off suggests, are hard for me to ask without throwing hundreds of lines of code at you. Hopefully this is more clear as to what I want to do.

Thanks for reading!
You could either put the information about how they take turns in Unit, so you can make the right decision that way, or keep NPC's and enemies in separate lists, as well as in the main list.
How different are the Friendly and Enemy classes? If all they do is encode which side the Unit is on, it might make more sense to add a member in Unit to indicate it, and not use inheritance at all.

Quote:Original post by guitarstar26
If I use the unit* as the array type, the problem comes when they need to "take a turn". I don't know how to determine if the current unit in array[0] is a friendly or enemy as they take turns differently.

Exactly how does their turn-taking behavior differ? As alvaro already suggested, perhaps a member variable that indicates which side a unit is on is all you need... or, as theOcelot suggested, use different lists - which can be used to look up what side a unit is on. You could also just do both.

Another thing to consider is separating unit controlling code from the unit code itself. That is, a unit may offer various move and attack functions, but enemy units will be controlled by some AI code, while player units will be controlled based on player input. In both cases, the same unit code can be used.

However, if enemy and friendly units do differ greatly, so subclassing Unit makes sense, then your Unit class could provide a virtual takeTurn() method. No matter what unit type you're actually dealing with, they all can take turns. Exactly how they take their turns is up to them - each class can have it's own implementation of takeTurn. That's called polymorphism. You may want to read up on it. :)
Create-ivity - a game development blog Mouseover for more information.

This topic is closed to new replies.

Advertisement