Question

class Shape
{
public:
  Shape() {size=0;}
  virtual bool isequal(const Shape& rhs){return false;};
  int size;
};

I have two classes (Rectangle and Cirle) which inherit from a class shape.

class Circle : public Shape
{
public:
  // snip
  Circle(int size): size(size) {}
  Circle(const Circle & rhs): size(rhs.size){}
  bool isequal( Shape &rhs)
  {
    Circle* rhsAsCircle = dynamic_cast<Circle*>(&rhs);
    if(rhsAsCircle == nullptr)
       return false; // not a Circle; can't be equal
    return size==rhsAsCircle->size;
  }
  int size;
};
class Rectangle : public Shape
{
public:
  Rectangle(int size1,int size2): size1(size1),size2(size2) {}
  Rectangle(const Rectangle & rhs): size1(rhs.size1),size2(rhs.size2) {}
  bool isequal( Shape &rhs)
  {
    Rectangle* rhs2 = dynamic_cast<Rectangle*>(&rhs);
    if(rhs2 == nullptr)
       return false; // not a Rectangle; can't be equal
    return (size1==rhs2->size1 && size2==rhs2->size2);
  }
  int size1;
  int size2; 
};

I use a class P to store different shapes in a vector and perform different operationg (ex adding rectangles/circles, deleting rectangles/circles.

class P
{
public:
  P(){}
  bool add(Rectangle rhs)
  {
    uint i=0;
    while (i<v.size() && rhs.isequal(*v[i])==false)
      i++;
    if (i!=v.size())
      return false;
    v.push_back(new Rectangle(rhs));
    return true;
  }
  bool add(Circle rhs)
  {
    uint i=0;
    while (i<v.size() && rhs.isequal(*v[i])==false)
      i++;
    if (i!=v.size())
      return false;
    v.push_back(new Circle(rhs));
    return true;
  }
  vector<Shape*> v;
};

To add a shape (rectangle or circle) I had to overload the function add. Isn't there a way to do only one function? Because circles and rectangle are shapes, no?

Was it helpful?

Solution

You could just pass the base class Shape to the add function. Just pass a pointer to the object to store it inside your vector vector<Shape*> v;

  bool add(Shape *shape)
  {
    uint i = 0;

    for( i = 0; i < v.size(); i++ ) {
      if(shape.isequal(*v[i]) == true)
        return false;
    }

    if ( i != v.size() )
      return false;

    v.push_back(shape);

    return true;
  }

Here is how this would work:

#include <iostream>
#include <vector>

using namespace std;

class Shape
{
protected:
    int m_size;
public:
    int getSize() { return m_size; }

    virtual bool isEqual(Shape *rhs) = 0;
};

class Rectangle : public Shape 
{
private:
    int m_size2;
public:
    Rectangle(int size, int size2) { m_size = size; m_size2 = size2; }

    int getSize2() { return m_size2; }

    bool isEqual(Shape *rhs)
    {
        Rectangle* rectangle = dynamic_cast<Rectangle*>(rhs);

        if(rectangle == 0)
            return false; // not a Rectangle

        return m_size == rectangle->getSize() && m_size2 == rectangle->getSize2();
    }
};

class Circle : public Shape
{
public:
    Circle(int size) { m_size = size; }

    bool isEqual(Shape *rhs)
    {
        Circle* circle = dynamic_cast<Circle*>(rhs);

        if(circle == 0)
            return false; // not a Circle

        return m_size == circle->getSize();
    }
};

class Container
{
private:
    vector<Shape*> v;
public:   
    ~Container()
    {
        for(int i = 0; i < v.size(); i++) {
            cout << "Removind element Nr. " << i << endl;
            delete v[i];
        }
        v.erase(v.begin(), v.end());
    }

    bool add(Shape *shape) 
    {
        for(int i = 0; i < v.size(); i++) {

            if( v[i] == shape ) { 
                cout << "  Element rejected (tried to add same element twice)" << endl;
                return false;
            }

            if( v[i]->isEqual(shape) ) {
                cout << "  Element rejected (an element with size " << v[i]->getSize() << " was already inside that list" << endl;
                return false;
            }

        }

        cout << "  Adding Element" << endl;
        v.push_back(shape);
        return true;
    }

    void print()
    {
        for(int i = 0; i < v.size(); i++) {
            cout << "Size of element " << i << ": " << v[i]->getSize() << endl;
        }
    }
};

int main()
{
   Rectangle *r        = new Rectangle(1, 2);
   Circle *c           = new Circle(2);
   Circle *c_reject    = new Circle(2);
   Rectangle *r_reject = new Rectangle(1, 2);

   Container container;
   container.add(r);
   container.add(c);

   container.add(r);        // will be rejected because r was already added
   container.add(c_reject); // will be rejected 
   container.add(r_reject); // will be rejected too

   container.print();

   return 0;
}

OTHER TIPS

First, replace the two add functions with this single function:

bool add(const Shape& shape)
{
    uint i=0;
    while (i<v.size() && shape.isequal(*v[i])==false)
        i++;
    if (i!=v.size())
        return false;
    v.push_back(shape.clone());
    return true;
}

Then, implement the function Shape* clone() in each class that inherits class Shape.

Finally, declare the pure virtual function virtual Shape* clone() = 0 in class Shape.

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