纯虚拟类和集合(向量?) [英] Pure Virtual Class and Collections (vector?)

查看:209
本文介绍了纯虚拟类和集合(向量?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个相当广泛使用虚拟类的图形应用程序。它具有:




  • 图片类,本质上是一组形状。


  • 一个形状类,它是纯虚拟的,并且有几个继承自它的类:





    • 多边形

    • 矩形





基本上,我的问题来自直到实现图片类,其基本上用于存储形状的集合。我目前使用Vector来存储形状,然而,显然这是错误的决定,因为Vector实例化这些形状,这是不好的,因为他们是纯虚拟的。



下面是我当前的代码库(总结了一下):

  class Figure {
public:
...
virtual〜Figure();
...
};

class Shape:public Figure
{
public:
...
virtual〜Shape(){}
virtual Shape * clone ()const =
...
};

类Polygon:public Shape
{
public:
...
virtual Shape * clone()const {return new Polygon ;}
...
private:
std :: vector< Point>点数;

};

class图片:public Figure {
public:
...
图片(图片& gd);
图片(const Picture&);
〜Picture();
void clear();
void add(const Shape&);
...
private:
std :: vector< Shape>形状;
Graphics * gfx;
};

//图片实现:
...
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.h:105:
错误:不能分配
的对象抽象类型'Shape'shape.h:12:
注意:因为下面的虚拟
函数在'Shape'中是纯的:
shape.h:58:注意:virtual void
Shape :: get(std :: istream&)shape.h:31:
注意:virtual void
Shape :: put :ostream&)const
shape.h:36:note:virtual void
Shape :: scale(const Point& double)
shape.h:40:note:virtual void
Shape :: translate(double,double)
shape.h:45:note:virtual void
Shape :: reflectHorizo​​ntally(double)
shape.h:49:note:virtual void
Shape :: reflectVertically(double)
shape.h:52:note:virtual
RectangularArea Shape :: boundingBox()
const shape.h:21:note:virtual
Shape * Shape :: clone()const
shape.h:55:注意:virtual void
Shape :: draw(Graphics&)const




那么什么是存储这些形状的理想方式。我应该使用什么样的集合来存储这些东西?



感谢

解决方案

当您需要多态性时,指针或引用。因为容器(或数组)不能存储引用,所以你必须使用指针。



基本上将你的图片类的向量改为:

  std :: vector< Shape *> 

并适当修改其他成员函数。



你不能/不应该将它们存储为值类型的原因是因为vector是一个同质的容器,即它只存储一种类型的数据(和只有一种类型 - 子类不是允许!这是因为向量将其数据存储在数组中,这需要知道它存储的对象的大小。如果这些对象的大小不同(它们可能用于不同的形状),那么它不能将它们存储在数组中。



如果将它们存储为指针,那么它们都具有相同的大小( sizeof(Shape *)),有访问形状的vtable,这是允许多态行为。


I'm working on a graphics application that is using virtual classes fairly extensively. It has:

  • A picture class, which is essentially a collection of shapes.

  • A shapes class, which is purely virtual and has a few classes that inherit from it:

    • Circle
    • Polygon
    • Rectangle
  • A Figure shape, which is any graphical figure (also virtual), shape inherits from this.

Essentially, my problem comes down to implementing the picture class, which is basically being used to store a collection of shapes. I'm currently using a Vector to store shapes, however, it's apparent that this is the wrong decision since Vector instantiates these shapes, which is not good as they are purely virtual.

Below is my current code base (summarized a bit):

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);
}
...

The error messages I'm getting are just a bunch of these:

picture.cpp:33: instantiated from here /opt/local/bin/../lib/gcc/sparc-sun-solaris2.10/4.4.1/../../../../include/c++/4.4.1/ext/new_allocator.h:105: error: cannot allocate an object of abstract type 'Shape' shape.h:12: note: because the following virtual functions are pure within 'Shape': shape.h:58: note: virtual void Shape::get(std::istream&) shape.h:31: note: virtual void Shape::put(std::ostream&) const shape.h:36: note: virtual void Shape::scale(const Point&, double) shape.h:40: note: virtual void Shape::translate(double, double) shape.h:45: note: virtual void Shape::reflectHorizontally(double) shape.h:49: note: virtual void Shape::reflectVertically(double) shape.h:52: note: virtual RectangularArea Shape::boundingBox() const shape.h:21: note: virtual Shape* Shape::clone() const shape.h:55: note: virtual void Shape::draw(Graphics&) const

So what is the ideal way to store these shapes. What kind of collection should I be using to store these things?

Thanks

解决方案

When you need polymorphism, you need to use either pointers or references. Since containers (or arrays) can't store references, you have to use pointers.

Essentially change your picture class's vector to:

std::vector<Shape*>

and appropriately modify the other member functions.

The reason why you can't/shouldn't store them as value types is because vector is a homogenous container i.e. it only stores data of one type (and only one type -- subclasses are not allowed!). The reason for this is because the vector stores its data in an array, which needs to know the size of the objects it's storing. If the sizes of these objects are different (which they might be for different shapes) then it can't store them in an array.

If you store them as pointers then they all have the same size (sizeof(Shape*)) and also have access to the shape's vtable, which is what allows polymorphic behaviour.

这篇关于纯虚拟类和集合(向量?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆