虚拟类和多态

时间:2014-04-29 14:54:51

标签: c++ class object polymorphism virtual

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

我有两个类(Rectangle和Cirle)继承自类形状。

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

我使用P类在矢量中存储不同的形状并执行不同的操作(例如,添加矩形/圆形,删除矩形/圆形。

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

要添加形状(矩形或圆形),我必须重载函数add。有没有办法只做一个功能?因为圆和矩形是形状,没有?

2 个答案:

答案 0 :(得分:1)

您可以将基类Shape传递给add函数。只需将指针传递给对象,即可将其存储在向量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;
  }

这是如何工作的:

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

答案 1 :(得分:0)

首先,用这个函数替换两个add函数:

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

然后,在继承类Shape* clone()的每个类中实现函数Shape

最后,在类virtual Shape* clone() = 0中声明纯虚函数Shape