Sign in to follow this  

Inheritance and base class pointers

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

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 :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
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. :)

Share this post


Link to post
Share on other sites

This topic is 2658 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this