简体   繁体   English

C ++多继承多态

[英]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 . std::vector<Shape*> shapes

The Problem is, that I want to call animate on all Shape* in shapes whose Base class also implements Animation. 问题是,我想在其基类也实现了Animation的shapes的所有Shape*上调用animate。 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. 但是即使它可以编译并正常运行并且render()被正确调用,但animate()却从未被调用。 What's the problem with this code. 这段代码有什么问题。

I tried using a = dynamic_cast<Animation*>(*it) as well but that just returns null. 我也尝试使用a = dynamic_cast<Animation*>(*it) ,但这只返回null。

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. 您发布的代码具有未定义的行为,因为您使用的C样式强制转换将始终“成功”,如果您的Shape实际上不是动画,则不会获得空指针。 No way to tell what comes afterwards, but segmentation fault is a probable option. 无法确定随后会发生什么,但是分段错误是一个可能的选择。

Use dynamic_cast<Animation*>(*it) ! 使用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. 如果*it不是Animation对象,则它将返回nullptr,这是正常的。

Maybe you have no Animation object in your list ... 也许您的列表中没有任何Animation对象...

The Problem is, that I want to call animate on all Shape* in shapes whose Base class also implements Animation. 问题是,我想在其基类也实现了Animation的形状中的所有Shape *上调用animate。 I tried doing this: 我尝试这样做:

According to your code Shape doesn't have a base class. 根据您的代码,Shape没有基类。 Eg 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);

Your Shape and your Animation does not have any relation. 您的ShapeAnimation没有任何关系。 You should cast your Shape in SomeAnimatedShape (and then in Animation if you want). 您应该在SomeAnimatedShape (如果需要,然后在Animation )中投射Shape

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++;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM