snangles_void
snangles_void

Reputation: 1

C++ multiple inheritance polymorphism

I have a few classes laid out like so:

class Shape { 
public:
    virtual void render() const = 0;
    ...other junk...
}
class Animation{
public:
    virtual void animate() = 0;
}

class SomeAnimatedShape : public Shape, public Animation{
    void render() { cout << "render called\n"; }
    void animate() { cout << "animate called\n"; }
}

and a std::vector<Shape*> shapes.

The Problem is, that I want to call animate on all Shape* in shapes whose Base class also implements Animation. I tried doing this:

std::vector<Shape*>::iterator it = shapes.begin();
while(it != shapes.end())
{
    Animation * a = (Animation *)(*it);
    if (a)
    {
        //a actually isn't nullptr
        a->animate();
    }
    (*it)->render();
    it++;
}

but even though it compiles and runs fine and render() gets called correctly, animate() is never called. What's the problem with this code.

I tried using a = dynamic_cast<Animation*>(*it) as well but that just returns null.

Upvotes: 0

Views: 567

Answers (3)

lelabo_m
lelabo_m

Reputation: 509

Your Shape and your Animation does not have any relation. You should cast your Shape in SomeAnimatedShape (and then in Animation if you want).

std::vector<Shape*>::iterator it = shapes.begin();
while(it != shapes.end())
{
   SomeAnimatedShape* a = dynamic_cast<SomeAnimatedShape*>(*it);
   // Animation* a = dynamic_cast<SomeAnimatedShape*>(*it); *Both should work*

   if (a)
      a->animate();

   (*it)->render();
   it++;
}

Upvotes: 0

Kiko
Kiko

Reputation: 359

The Problem is, that I want to call animate on all Shape* in shapes whose Base class also implements Animation. I tried doing this:

According to your code Shape doesn't have a base class. E.g. it is not possible to have a code like this:

 shapes.push_back(new Animation());

This will prompt a compile error.

Most likely you have :

shapes.push_back(new Shape());

If you want to have a runtime check then you need to use:

Animation * a = dynamic_cast<Animation *>(*it);

Upvotes: 0

Gabor Angyal
Gabor Angyal

Reputation: 2255

The code you posted has an undefined behaviour, because the C-style cast you are using will always "succeed" in the sense that you will not get a null pointer if your Shape is not actually an animation. No way to tell what comes afterwards, but segmentation fault is a probable option.

Use dynamic_cast<Animation*>(*it)! And then the code you wrote seems fine. if *it is not an Animation object then it will return a nullptr, that is normal.

Maybe you have no Animation object in your list ...

Upvotes: 4

Related Questions