c++encapsulationdata-hiding

C++ - geometric primitives class hierarchy


I'm new in C++, and I would like to work on my first tutorial.

I want to write a program which shall implement search over a list of objects representing graphical symbols.

The list contains Rectangles, described by two edge lengths, and circles, described by radius.

I also want to create a search procedure, that takes in a list and rectangle edge length and returns another list containing only these symbols that fit into the given rectangle.

Implementation of the list (and the search function) should allow to extend the list of accepted symbols (e.g. add polygon) without modifying any of the existing code.

What kind of approach should I follow? Could you give me a similar example to my aim?


Solution

  • This is a use for polymorphism - you'll have std::vector<Object*> or std::vector<std::shared_ptr<Object>> to hold the list of objects.

    Object should essentially look like this:

    class Object
    {
    public:
        virtual ~Object() = default;
    
        // needs to be implemented by deriving classes i.e. Rectangle and Circle
        virtual bool fitsIn(Rectangle const& r) const = 0;
    };
    

    And of course Rectangle and Circle will inherit from it:

    class Rectangle : public Object
    {
        int x, y, w, h;
    
    public:
        Rectangle(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) {}
    
        virtual bool fitsIn(Rectangle const& r) const override
        {
            // return whether can fit in r based on this object's and r's x, y, w and h
        }
    };
    

    Then you'll be able to add it into the list, iterate through and call fitsIn on every element, pushing it to the other vector depending on what fitsIn returns:

    std::vector<std::shared_ptr<Object>> objects, fitting_objects;
    
    objects.push_back(new Rectangle(10, 10, 20, 20)); // classic polymorphism spectacle
    
    // rectangle for the area containing the objects we're looking for
    Rectangle r(5, 5, 30, 30);
    
    for(auto const& object : objects)
        if(object.fitsIn(r))
            fitting_objects.push_back(object);