I'm designing a module to determine if a Point
is inside/outside some boundaries defined by geometric objects. In order to do this, I have the following base class :
#pragma once
#include "Point.h"
class IBound
{
public:
virtual bool isInside(const Point& point) const = 0;
virtual ~IBound() {}
};
I want to be able to tell if a point is inside many different boundaries and outside many other boundaries, so I created an object called GeometricBoundaries :
#pragma once
#include "IBound.h"
using BoundariesList = std::vector<IBound*>;
class GeometricBoundaries : public IBound
{
public:
GeometricBoundaries(const BoundariesList& boundaries_to_include, const BoundariesList& boundaries_to_exclude)
: m_boundaries_to_include(boundaries_to_include), m_boundaries_to_exclude(boundaries_to_exclude) {}
bool isInside(const Point& point) const override;
/*
Since we're going to hold on to raw pointers, we don't want an instance of this object to be passed around too much.
Deleting the copy constructor/assignemnt operator makes sure that this object cannot be copied or moved,
*/
GeometricBoundaries(const GeometricBoundaries&) = delete;
GeometricBoundaries& operator=(const GeometricBoundaries&) = delete;
private:
const BoundariesList m_boundaries_to_include;
const BoundariesList m_boundaries_to_exclude;
};
So, to create a GeometricBoundaries
object, I'd need to do something like this :
IBound* square_inc = new Square(...);
IBound* square_exc = new Square(...);
IBound* ellipse_inc = new Ellipse(...);
IBound* circle_exc = new Circle(...);
GeometricBoundaries geometric_boundaries(BoundariesList{square_inc, ellipse_inc}, BoundariesList{square_exc, circle_exc});
Instead of using smart pointers, I decided to use raw pointers. Since I don't really need reference counts and I only want to be able to use polymorphism, I couldn't decide which smart pointer was the "best" in this case and the raw one made more sense. But now, this can lead to some problems where the geometric_boundaries
object could live longer than, for example, square_exc
or the opposite, both cases would, I think, lead to some memory leaks or undefined behavior.
My intuition tells me I should try to make GeometricBoundaries as "short lived" as possible by deleting the copy/move constructors/assignment operators, but I think this might be the wrong way. I'm still pretty new to C++ and I'd like to know what's the safest way to use such a structure by following the best practices available in CP++11.