C++ C++;多重遗传多态性

C++ C++;多重遗传多态性,c++,C++,我有几门课是这样安排的: 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 << "r

我有几门课是这样安排的:

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"; }
}
但是,即使它编译并运行良好,并且正确地调用了
render()
,也永远不会调用
animate()
。这个代码有什么问题


我也尝试过使用
a=dynamic\u cast(*it)
,但只返回null

您发布的代码具有未定义的行为,因为您正在使用的C样式转换将始终“成功”,即如果您的形状实际上不是动画,您将不会获得空指针。没有办法知道接下来会发生什么,但分割错误是一个可能的选择

使用
dynamic\u cast(*it)
!然后你写的代码看起来很好。如果
*它
不是
动画
对象,那么它将返回一个null ptr,这是正常的


可能您的列表中没有
动画
对象…

您发布的代码具有未定义的行为,因为您使用的C样式转换将始终“成功”,即如果您的形状实际上不是动画,您将不会获得空指针。没有办法知道接下来会发生什么,但分割错误是一个可能的选择

使用
dynamic\u cast(*it)
!然后你写的代码看起来很好。如果
*它
不是
动画
对象,那么它将返回一个null ptr,这是正常的

可能您的列表中没有
动画
对象

问题是,我想在基类也实现动画的形状中对所有形状*调用animate。我试着这样做:

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++;
}
根据你的代码形状没有基类。例如,不可能有这样的代码:

 shapes.push_back(new Animation());
这将提示编译错误

您很可能有:

shapes.push_back(new Shape());
如果要进行运行时检查,则需要使用:

Animation * a = dynamic_cast<Animation *>(*it);
Animation*a=dynamic_cast(*it);
问题是,我想在基类也实现动画的形状中对所有形状*调用animate。我试着这样做:

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++;
}
根据你的代码形状没有基类。例如,不可能有这样的代码:

 shapes.push_back(new Animation());
这将提示编译错误

您很可能有:

shapes.push_back(new Shape());
如果要进行运行时检查,则需要使用:

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

你的
形状
和你的
动画
没有任何关系。 您应该在
SomeAnimatedShape
中投射
Shape
(如果需要,可以在
动画中投射)

std::vector::iterator it=shapes.begin();
while(it!=shapes.end())
{
SomeAnimatedShape*a=动态投影(*it);
//动画*a=动态_cast(*it);*两者都应该可以工作*
如果(a)
a->animate();
(*it)->render();
it++;
}

你的
形状
和你的
动画
没有任何关系。 您应该在
SomeAnimatedShape
中投射
Shape
(如果需要,可以在
动画中投射)

std::vector::iterator it=shapes.begin();
while(it!=shapes.end())
{
SomeAnimatedShape*a=动态投影(*it);
//动画*a=动态_cast(*it);*两者都应该可以工作*
如果(a)
a->animate();
(*it)->render();
it++;
}

True,但也可以有
形状。向后推(new SomeAnimatedShape())。那没问题。在本例中,将调用Animation::animate()。为True,但也可以有
形状。向后推(new SomeAnimatedShape())。那没问题。在这种情况下将调用Animation::animate()。下面的dynamic_cast答案是您所问问题的答案,但该cast的出现通常表明设计需要重新思考。你还会考虑存储所有动画的向量吗?例如,我建议使用构图而不是继承。AndyNewman的建议也很好。将组件(而不仅仅是复合对象)存储在向量中是一种有效且简单的优化方法。@RonakPatel他有两个不同的接口,以及实现这两个接口的对象。这是一个完美的例子,说明多重继承是唯一正确的解决方案。还有混合蛋白的情况。你说多重继承在实践中不好的说法完全是错误的。@AndyNewman他处理的是多态对象,所以把它们放在一个向量中是不允许的。@RonakPatel既然你能把它复杂化,为什么还要简单呢?C++中增加了多重继承和<代码> DyrimeCase> <代码>,以支持这种场景。在一些不同的环境中,他可能也有一个
动画的向量,并且需要对那些支持
形状
界面的成员做一些特殊的事情。下面的动态演员回答是对您所问问题的回答,但该演员的出现往往表明设计需要重新思考。你还会考虑存储所有动画的向量吗?例如,我建议使用构图而不是继承。AndyNewman的建议也很好。将组件(而不仅仅是复合对象)存储在向量中是一种有效且简单的优化方法。@RonakPatel他有两个不同的接口,以及实现这两个接口的对象。这是一个完美的例子,说明多重继承是唯一正确的解决方案。还有混合蛋白的情况。你说多重继承在实践中不好的说法完全是错误的。@AndyNewman他处理的是多态对象,所以把它们放在一个向量中是不允许的。@RonakPatel既然你能把它复杂化,为什么还要简单呢?C++中增加了多重继承和<代码> DyrimeCase> <代码>,以支持这种场景。在某些不同的上下文中,他可能也有一个
动画的向量
,并且需要对那些支持
形状
接口的成员做一些特殊的事情。@AaronMcDaid当然不是;向量包含指针