how do i use the find algorithm to check if a certain object exists in a vector.
I have a base class called Shape and derived classes Circle and Line.
Circle has 3 attributes , x location , y location and radius.
I would like to check if the Circle c1(1,1,1) exists in the vector<std::shared_ptr<Shape>> v.
Btw, Line should not be derived from Shape because it is not a Shape. Functions like Area and perimeter should be able to be applied to all classes derived from Shape.
class DrawingEntity; // has a virtual draw function which is inherited by all derived classes
class Shape : public DrawingEntity; // virtual Area and Perimeter functions
class Triangle : public Shape;
class Circle : public Shape;
class RegularPolygon : public Shape;
class Line : public DrawingEntity;
class Annotation : public DrawingEntity; // graphical text
std::vector<std::shared_ptr<Shape>>::iterator it = std::find_if(v.begin(), v.end(), [](std::shared_ptr<Shape> shape)
{
std::shared_ptr<Circle> c = std::dynamic_pointer_cast<Circle>(shape);
...
return is_ok;
});
so Line should not derive from Shape ?
Generally: If a class needs things provided by another class it may inherit from that class. Since a line has a with it is rather a special case of a rectangle. So I would say yes, a line is a kind of shape.
Btw, Line should not be derived from Shape because it is not a Shape. Functions like Area and perimeter should be able to be applied to all classes derived from Shape.
Here's the thinking behind the inheritance tree above:
Public inheritance implies a "IS A" relationship. In the SOLID wiki page, the L is for Liscov substitution. So functions like Area and perimeter should be able to be applied to base and derived class Shapes. Line doesn't fit into inheritance from Shape, neither does Annotation. But one thing they all have in common is a draw function, so I made the DrawingEntity base class, and all the derived classes inherit and override it's virtual draw function.
Now one can have a container of pointer or reference (via std::reference_wrapper) to DrawingEntity (the base class). We populate this with pointers / references to the derived classes. Next use a range base for loop to call the draw function via each pointer/reference. The compiler calls the correct function because a pointer/reference to a derived class is a valid reference to a base class . This is why there is no need for a dynamic_cast.
-> bool determines the return value. It can usually be automatically determined by the compiler when using the return statement (or not -> void).
So simplified:
1 2 3 4 5 6 7 8 9 10 11 12 13
std::vector<std::shared_ptr<Shape>>::iterator it = std::find_if(v.begin(), v.end(), [](std::shared_ptr<Shape> shape)
{
std::shared_ptr<Circle> c= std::dynamic_pointer_cast<Circle>(shape);
bool is_ok = false;
if(c)
{
is_ok = ((*c) == Circle{1,1,1}); // Note: You need to overload operator==(...) in order to make this work.
}
return is_ok;
});