C++重写的方法没有被调用
Shape.h
namespace Graphics {
class Shape {
public:
virtual void Render(Point point) {};
};
}
Rect.h
namespace Graphics {
class Rect : public Shape {
public:
Rect(float x, float y);
Rect();
void setSize(float x, float y);
virtual void Render(Point point);
private:
float sizeX;
float sizeY;
};
}
struct ShapePointPair {
Shape shape;
Point location;
};
像这样使用:
std::vector<Graphics::ShapePointPair> theShapes = theSurface.getList();
for(int i = 0; i < theShapes.size(); i++) {
theShapes[i].shape.Render(theShapes[i].location);
}
此代码最终调用 Shape::Render
而不是 Rect::Render
我假设这是因为它正在转换Rect
到 Shape
,但我不知道如何阻止它这样做。我试图通过重写 Render 方法来让每个形状控制它的渲染方式。
关于如何实现这一目标有什么想法吗?
Shape.h
namespace Graphics {
class Shape {
public:
virtual void Render(Point point) {};
};
}
Rect.h
namespace Graphics {
class Rect : public Shape {
public:
Rect(float x, float y);
Rect();
void setSize(float x, float y);
virtual void Render(Point point);
private:
float sizeX;
float sizeY;
};
}
struct ShapePointPair {
Shape shape;
Point location;
};
Used like this:
std::vector<Graphics::ShapePointPair> theShapes = theSurface.getList();
for(int i = 0; i < theShapes.size(); i++) {
theShapes[i].shape.Render(theShapes[i].location);
}
This code ends up calling Shape::Render
and not Rect::Render
I'm assuming this is because it is casting the Rect
to a Shape
, but I don't have any idea how to stop it doing this. I'm trying to let each shape control how it is rendered by overriding the Render
method.
Any ideas on how to achieve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这是您的问题:
您正在存储一个
Shape
。您应该存储一个Shape *
或一个shared_ptr
或其他东西。但不是Shape
; C++ 不是 Java。当您将
Rect
分配给Shape
时,仅复制Shape
部分(这是对象切片) 。Here's your problem:
You are storing a
Shape
. You should be storing aShape *
, or ashared_ptr<Shape>
or something. But not aShape
; C++ is not Java.When you assign a
Rect
to theShape
, only theShape
part is being copied (this is object slicing).这个问题称为切片 - 当复制到基础时,您会丢失派生功能。
为了避免这种情况,使用指向基类的指针,即
This problem is called slicing - you lose the derived functionality when copying to a base.
To avoid this use pointers to the base class, i.e.
问题是,在您的向量中,您存储的是 Shape 对象的副本,并且复制 Shape 对象不会复制其派生类的数据或功能 - 您是 切片 多态性。
使用 new 和 delete 管理对象,并安排向量存储指向它们的指针。
The problem is that in your vector you are storing copies of Shape objects, and copying a Shape object does not copy the data or functionality of its derived classes - you're slicing the polymorphism away.
Manage the objects using new and delete, and arrange for your vector to store pointers to them.
多态性仅适用于指向形状的指针,不适用于形状对象。
The polymorphism will only work from a pointer to a shape, not from a shape object.
您正在直接访问形状对象,以便覆盖工作,您需要通过指针或引用访问该对象。
例如,当您将 Shape 分配到 ShapePointPair 中时,代码将“切片”对象并仅将 Shape 位复制到 ShapePointPair 中,
这样做意味着您必须监视内存管理 - 因此您可以在结构中使用智能指针
形状点对 {
智能指针形状;
点位置;
};
You are accessing the shape object directly for the override to work you need to access the object via a pointer or references.
For example when you assigne the Shape into the ShapePointPair the code will 'slice' the object and only copy the Shape bit into the ShapePointPair
Doing this will mean you have to watch memory management - so you could use a smart pointer in the struct
ShapePointPair {
smart_pointer shape;
Point location;
};
不,这不是铸造。
您可以改为存储对基类 Point 的引用:
必须在结构的构造时设置此引用
形状点对。为此,向 ShapePointPair 添加一个构造函数
目的。它必须传递(新创建的)实例
矩形。
还要遵守内存管理职责(正确的
编写的析构函数等)。
No, it is not casting.
You can instead store a reference to baseclass Point:
This reference must be set at construction time for struct
ShapePointPair. Add a constructor to ShapePointPair for this
purpose. It must be passed (newly created) instances of
Rect.
Also observe the memory management responsiblities (proper
written destructors, etc.).
您可以尝试 boost::ptr_vector
http://www .boost.org/doc/libs/1_40_0/libs/ptr_container/doc/ptr_container.html
You could try boost::ptr_vector
http://www.boost.org/doc/libs/1_40_0/libs/ptr_container/doc/ptr_container.html
我不确定能否解释清楚,因为我的英语很差。
我认为你应该使用它的引用或指针类型。
因为形状准确地定义了它必须做什么。
如果您直接使用代码,您的孩子会尝试复制并执行形状的工作。
这就是为什么你的覆盖功能不起作用的原因。
使用指针或引用
像这样。
pointer.h
reference.h
*ps:我个人使用抽象函数(virtual void Something() = 0;)。
因为有时我也忘记了它,所以我将其捕获为语法错误。
I'm not sure to explain well because of my english is poor.
I think you should have to use it reference or pointer type.
because shape is exactly defined what it has to do.
If you use your code directly, your child try to copy and do shape's working.
That is why doesn't work your override function.
use pointer or reference
like this.
pointer.h
reference.h
*ps: personally i use abstract function(virtual void something() = 0;).
because i also forgot about it sometimes so i catch it as syntax error.