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当然不是;向量包含指针