Pregunta

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?

¿Fue útil?

Solución

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

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top