I want a class template template<std::size_t N> Shape
, where the template parameter N
represents the dimension of the Shape
. There should be a limited number of predefined Shape
s, such as Shape<2> SQUARE
, Shape<3> CUBE
and Shape<3> SPHERE
. I might add more predefined Shape
s in the future.
I want Shape
objects only to be constructible as any of the predefined Shape
s. Since the properties of these predefined Shape
s remain the same at all time, it would be optimal to have them stored only once, and to have new Shape
objects refer to them.
At this moment, I have the following implementation:
// Flag for the possible shapes
enum class Tag
{
SPHERE,
CUBE,
SQUARE
};
template<std::size_t N>
class Shape
{
public:
// Predefined shapes.
static const Shape<3> SPHERE;
static const Shape<3> CUBE;
static const Shape<2> SQUARE;
// Information stored about the given shapes
const Tag tag; // tag specifying the shape
const double v; // Shape volume/area
const std::array<double, 2*N> surrounding_box; // Storing intervals for a surrounding box
//... Some other information that depends on template parameter N
private:
// Private constructor. This prevents other, unintended shapes from being created
Shape(Tag tag, double v, const std::array<double, 2*N> surrounding_box):
tag{tag}, v {v}, surrounding_box {surrounding_box} {};
};
// Initialization of predefined shape: SPHERE
template<std::size_t N>
const Shape<3> Shape<N>::SPHERE(Tag::SPHERE, 3.0,{{0.0,2.7,0.0,2.7,0.0,2.7}});
// Initialization of predefined shape: CUBE
template<std::size_t N>
const Shape<3> Shape<N>::CUBE(Tag::CUBE, 1.0,{{0.0,1.0,0.0,1.0,0.0,1.0}});
// Initialization of predefined shape: SQUARE
template<std::size_t N>
const Shape<2> Shape<N>::SQUARE(Tag::SQUARE, 1.0,{{0.0,1.0,0.0,1.0}});
This implementation has a few problems:
- Every instance of
Shape
contains all the predefinedShape
s (As pointed out in the comments of this question); - Fore every instance of
Shape
that is created, the content of the predefinedShape
s gets copied; - Even a
Shape<3>
object contains theShape<2> SQUARE
. - ...
I would like to know what would be a better design pattern to achieve the above described goals.
I was thinking of using the Tag
as a constructor parameter and using some kind of factory. However, I have problems to get the implementation details right due to the template complications and the fact that I only want predefined Shape
s to be constructible.