Question

I am working on polymorphism in c++. I have a shape abstract class and a few class which inherit shape class. now I want to have a list of shape. but when I use shape for type of array it says "array of abstract class is not allowed",also I know we can not create instances of abstract class. what should I do with this problem?

class List
{
    int count;
    int size;
    shape* shapes;


public:
    int getCount()
    {
        return count;
    }

    List(int n=4)
    {
        count=0;
        shapes=new shape[n];
        size=n;
    }

    ~List()
    {
        if(shapes!=NULL)
            delete[] shapes;    
        shapes=NULL;
    }

    int getItem(int index)
    {
        return shapes[index];
    }
void insert(shape& sh,int index)
{
    if(index<=-1)
    {
        cout<<"Index should be non-negative."<<endl;
        return;
    }
    if(index>count)
        index=count;
    for(int i=count-1;i>=index;i--)
        shapes[i+1]=shapes[i];
    shapes[index]=num;
    count++;
}



};
Was it helpful?

Solution

You need an array of pointers to an abstract class. Ie, Shape** shapes, shapes = new Shape*[n].


The issue with shapes[index]=sh is that sh is a reference to a Shape, not a pointer to one. You can modify insert so it looks like:

void insert(Shape* shape, int index) {
   // ...
   shapes[index] = sh;
}

or do something like:

void insert(Shape& shape, int index) {
   // ...
   shapes[index] = &sh;
}

OTHER TIPS

You need to use an array of pointers to Shape or better yet use an STL container of smart pointers to Shape. Something like:

#include <vector>
#include <memory>

struct Shape {
  virtual ~Shape() = 0;
};
Shape::~Shape(){}

struct Square : public Shape {
};

class List {
    std::vector<std::unique_ptr<Shape>> shapes;
  public:
    int          getCount() const {return shapes.size();}
    const Shape* getItem(int index) const;
    void         insert(std::unique_ptr<Shape>, int index);
};

const Shape*
List::getItem(int index) const {
  if (index < 0 || (size_t) index >= shapes.size())
    return nullptr;

  return shapes[index].get();
}

void
List::insert(std::unique_ptr<Shape> sh, int index) {
  if (index < 0)
    return;

  if ((size_t)index >= shapes.size())
    index = shapes.size();

  shapes.insert(shapes.begin() + index, std::move(sh));
}

int main() {
  List list;
  list.insert(std::unique_ptr<Shape>(new Square()), 0);
  list.insert(std::unique_ptr<Shape>(new Square()), 0);
  list.insert(std::unique_ptr<Shape>(new Square()), 2);
  const Shape* sh = list.getItem(0);
}

Or better still, if possible, don't write your own List class just use an STL container of smart pointers directly instead!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top