Question

I have a virtual class Shape. class Rectangle, Triangle, Circle inherit from Shape and have different characteristics (size, number of side...). I want to store different shape in a structure (let's say a vector).

so my vector would be: vector<Shape*> myvec;

I would like to know how it is possible to know if a given instance of a shape is present in the vector (ex: new Circle(diameter 10);).

I have heard about dynamic cast but I don't understand at all how to use it?

class Shape
{
public:
  Shape(){}
  virtual int Size()=0;
  virtual int Sides()=0;
  virtual bool isequal(const Shape & rhs)=0;
  int size,sides;
};

class Circle : public Shape
{
public:
  Circle(int diameter):size(diameter)
  {
    sides=0;
  }
  bool isequal(const Circle &rhs)
  {
    return size==rhs.size;
  }
  int size,sides;
};

class Rectangle: public Shape
{
  Rectangle(int nbsides,int size1,int size2 ): sides(nbsides),size1(size1),size2(size2){}
   bool isequal(const Rectangle &rhs)
  {
    return (size1==rhs.size1 && rhs.size2==size2);
  }
  int sides,size1,size2;
};
Was it helpful?

Solution

dynamic_cast is right:

Shape* shape = myvec[0];
Circle* circle = dynamic_cast<Circle*>(shape);
if(circle != nullptr)
   ; // it's a Circle! Do something circly.
else
   ; // it's not a Circle. Do something else.

But a better answer to the question is that, in a perfect world, you should use polymorphism such that it is rarely if ever necessary to do this.

Based on the additional comments below, I think you might want to use a pure virtual isequal() in Shape, with dynamic_casts inside the various implementations (the inside of a polymorphic comparison function is one of the few places I can use dynamic_cast without feeling the need to wash my hands afterwards :) ).

// edited out code that isn't directly relevant

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

class Circle : public Shape
{
public:
  // snip

  virtual bool isequal(const Shape &rhs) override
  {
    Circle* rhsAsCircle = dynamic_cast<Circle*>(&rhs);
    if(rhsAsCircle == nullptr)
       return false; // not a Circle; can't be equal
    return size==rhsAsCircle->size;
  }
};

Then elsewhere:

Circle searchCircle(10);

for(Shape* shape : myvec)
   if(shape->isequal(searchCircle))
      ; // we have a match!
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top