我正在开发一个图形应用程序,该应用程序相当广泛地使用虚拟类。它有:
本质上,我的问题归结于实现图片类,它基本上用于存储形状的集合。我目前正在使用 Vector 来存储形状,但是,显然这是错误的决定,因为 Vector 实例化了这些形状,这不好,因为它们是纯虚拟的。
以下是我当前的代码库(总结了一下):
class Figure {
public:
...
virtual ~Figure();
...
};
class Shape: public Figure
{
public:
...
virtual ~Shape() {}
virtual Shape* clone() const = 0;
...
};
class Polygon : public Shape
{
public:
...
virtual Shape* clone() const {return new Polygon(*this);}
...
private:
std::vector<Point> points;
};
class Picture: public Figure {
public:
...
Picture(Graphics& gd);
Picture (const Picture&);
~Picture();
void clear();
void add (const Shape&);
...
private:
std::vector<Shape> shapes;
Graphics* gfx;
};
//Picture implementation:
...
Picture::Picture(Graphics& gd)
{
gfx = &gd;
}
Picture::Picture(const Picture& a)
{
shapes = a.shapes;
}
Picture::~Picture()
{
clear();
}
void Picture::clear()
{
shapes.clear();
}
void Picture::add (const Shape& shp)
{
Shape* nshp = shp.clone();
shapes.push_back(*nshp);
}
...
我收到的错误消息只是其中的一些:
picture.cpp:33:实例化自
这里
/opt/local/bin/../lib/gcc/sparc-sun-solaris2.10/4.4.1/../../../../include/c++/4.4.1/ext/new_allocator。小时:105:
错误:无法分配对象
抽象类型“形状”shape.h:12:
注意:因为以下虚拟
'Shape' 中的函数是纯函数:
shape.h:58:注意:虚拟虚空
形状::get(std::istream&) shape.h:31:
注:虚空
形状::put(std::ostream&) const
shape.h:36:注意:虚拟虚空
Shape::scale(const Point&, double)
shape.h:40:注意:虚拟虚空
形状::翻译(双,双)
shape.h:45:注意:虚拟虚空
形状::水平反射(双)
shape.h:49:注意:虚拟虚空
形状::垂直反射(双)
shape.h:52:注释:虚拟
矩形区域形状::boundingBox()
const shape.h:21:注意:虚拟
形状* 形状::clone() const
shape.h:55:注意:虚拟虚空
形状::绘制(图形&) const
那么存储这些形状的理想方式是什么?我应该使用什么样的集合来存储这些东西?
Thanks
当需要多态性时,需要使用指针或引用。由于容器(或数组)无法存储引用,因此必须使用指针。
本质上将图片类的向量更改为:
std::vector<Shape*>
并适当修改其他成员函数。
不能/不应该将它们存储为值类型的原因是因为向量是同质容器,即它只存储一种类型的数据(并且only一种类型——不允许有子类!)。原因是向量将其数据存储在数组中,该数组需要知道其存储的对象的大小。如果这些对象的大小不同(它们可能具有不同的形状),则无法将它们存储在数组中。
如果将它们存储为指针,那么它们都具有相同的大小(sizeof(Shape*)
)并且还可以访问形状的 vtable,这就是允许多态行为的原因。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)