0

I wasn't sure how to exactly title this, but I am trying to figure out something with polymorphism.

So basically, I want to have an array of the parent class (object) that holds a bunch of it's child classes (ones that are and aren't collidable). However, I want to be able to put this array into a loop and run the collision function for only the collidable child class, but since the other child class doesn't have a collide function, how can I do this?

(Looks something like this)

class Object
{
protected:
    Image image; // Pseudo code to make point
public:
    void Collision() = 0;

    //Constructor/Destructor
    Object(void);
    ~Object(void);

}; 

class Collidable : Object
{
private:
    Position myPosition; // Pseudo code to make point
public:
    void Collision(); // Has collision function for parent class

    //Constructor/Destructor
    Collidable(void);
    ~Collidable(void);
};

class Uncollidable : Object
{
private:
    Position myPosition; // Pseudo code to make point
public:
    // No collision function for parent class

    //Constructor/Destructor
    Uncollidable(void);
    ~Uncollidable(void);
};

int main()
{
    Collidable collide1, collide2, collide3;
    Uncollidable uncollide1, uncollide2, uncollide3;
    Object *objects[] { collide1, collide2, uncollide1, uncollide2, uncollide3, collide3 };

    for(int i = 0; i < 6; i++)
    {
        objects[i].Collide(); // Should not work.
    }

    return 0;
}

^(this was just an example to help show my question, do pardon some of the syntax errors if any)

I'm pretty sure, however, that something like this would be an error since void Collide() doesn't exist in the Uncollidable class. So how might I be able to still run the void Collide() function in the loop while avoiding error? Or is something like this impossible and I just have to make two separate arrays?

I hope I explained my question well.

(I tried to research this, but every time I tried I just got sent to the basics of polymorphism)

Uulamock
  • 330
  • 1
  • 3
  • 15
  • maybe relevant, [how to check if member function exists](http://stackoverflow.com/questions/13786888/check-if-member-exists-using-enable-if) – M.M May 30 '14 at 05:14

1 Answers1

2

You can just do this:

for(int i = 0; i < 6; i++)
{
  Collidable c = dynamic_cast<Collidable*>(objects[i]);

  if(c != nullptr) // dynamic_cast will return null if objects[i] is not of type Collidable
    c->Collide(); // Should work.
}

In your code there is one bug, you have made Collide() pure virtual in class Object, but you are not overriding it in Uncollidable. It will not work. Either override it in Uncollidable (which is inappropriate), or give a default body to Object::Collide() (which is inappropriate also).

There is a better design, put all the common interface in Object, separate out different behaviors in other interface. It will lead to good OO design ( compliant with IS-A relationship)

class Object
{
 protected:
   Image image; // Pseudo code to make point
 public:
   Object(void);
  ~Object(void);
 //other common interface
 }; 

class Collidable // this is an interface that represent 'collidable' behavior
{
  public:
   virtual void Collision() = 0;
}


class CollidableObject : public Object, public Collidable
{  ... }

class UncollidableObject : public Object
{ ...  }

Note: Object must be inherited publicly, otherwise you will not be able to treat object os CollidableObject and UncollidableObject as object of Object.

Rakib
  • 7,435
  • 7
  • 29
  • 45
  • Thanks a bunch for your reply, it helped a lot, but could you possibly elaborate a bit more on "common interface" ? I have been studying C++ for a few years now and am finally getting into the advanced stuff, but there is still a lot I don't know (mostly terminology). If you could also give me some key terms to help me research good OO design, that would help me a ton as well since I tend to lack vocab. Again, thank you! – Uulamock May 30 '14 at 03:07
  • as a startup go through [the inheritance part](http://www.parashift.com/c++-faq/). I will try to collect more and post later – Rakib May 30 '14 at 03:11
  • Thank you. This helps me, probably, more than you know. – Uulamock May 30 '14 at 03:18
  • 1
    +1 for this class design (although you may want public inheritance from Object) – M.M May 30 '14 at 05:16
  • @MattMcNabb, infact, inheriting publicly is a must here. thanks – Rakib May 30 '14 at 05:19
  • @Uulamock, by *common interface* I meant methods that are common for both `Collidable` and `UnCollidable` objects. For ex. `Collision` is not common to both, so it was removed. – Rakib May 30 '14 at 05:21
  • It's amazing how much I still don't know. So, basically, I should make an ABC that contains common virtual methods that would apply to anything that inherits it, and then make the derived classes actually do something with these functions? (the derived classes that are actually going to be declared and used that is) Thanks again for helping me. I just want to make sure I am learning things properly since I don't know much about good OO design. – Uulamock May 30 '14 at 16:26