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
方法。
任何想法如何实现这一目标?
这是你的问题:
struct ShapePointPair {
Shape shape;
Point location;
};
您存储Shape
。 你应该存储Shape *
,或shared_ptr<Shape>
或东西。 但不是一个Shape
; C ++是不是Java。
当您指定一个Rect
的Shape
,只有Shape
的部分被复制(这是对象切片 )。
这个问题被称为切片 - 复制到基地当你失去的衍生功能。 为了避免这种使用指针的基类,即
std::vector<Graphics::Shape*> s;
s.push_back(&some_rect);
问题是,在您的载体要存储形状对象的副本,并复制一个形状对象不复制其派生类的数据或功能-你切的多态了。
使用新的管理对象和删除,并安排您的矢量的指针存储到他们。
所述多态性将只从一个指针到工作的形状,而不是从一个形状对象。
你是直接访问图形对象的覆盖工作,你需要通过指针或引用访问对象。
例如,当你assigne造型融入ShapePointPair代码将“片”的对象,只有形状位复制到ShapePointPair
这样做将意味着你必须注意内存管理 - 所以你可以使用在结构ShapePointPair {smart_pointer形状的智能指针; Point location; 点位置; }; };
不,它不是铸造。
您可以代替存储参照基类点:
struct ShapePointPair {
Shape shape;
Point &location;
};
此引用必须在施工时间结构ShapePointPair进行设置。 添加一个构造函数来ShapePointPair用于这一目的。 它必须通过(新建)矩形的实例。
此外观察内存管理responsiblities(适当的书面析构函数等)。
你可以尝试的boost :: ptr_vector
http://www.boost.org/doc/libs/1_40_0/libs/ptr_container/doc/ptr_container.html
我不知道的好,因为我的英语很差解释。
我想你应该有使用它引用或指针类型。 因为形状精确定义它有什么做的。
如果你直接使用你的代码,你的孩子尝试复制和形状做的工作。 这就是为什么不工作,你的覆盖功能。
使用指针或引用这样。
pointer.h
class Parent {
public:
virtual void work() { printf("parent is working now\n"); }
};
class Child1 {
public:
virtual void work() { printf("child1 is working now\n"); }
};
class Child2 {
public:
virtual void work() { printf("child2 is working now\n"); }
};
struct Holder {
Parent* obj1;
Parent* obj2;
};
int main() {
Child1 child1;
Child2 child2;
Holder holder = { &child1, &child2 };
holder.obj1->work();
holder.obj2->work();
return 0;
}
reference.h
class Parent {
public:
virtual void work() { printf("parent is working now\n"); }
};
class Child1 {
public:
virtual void work() { printf("child1 is working now\n"); }
};
class Child2 {
public:
virtual void work() { printf("child2 is working now\n"); }
};
struct Holder {
Parent& obj1;
Parent& obj2;
};
int main() {
Child1 child1;
Child2 child2;
Holder holder = { child1, child2 };
holder.obj1.work();
holder.obj2.work();
return 0;
}
* PS:我个人使用抽象函数(虚拟无效的东西()= 0;)。 因为我也忘了,有时,所以我抓住它的语法错误。