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 Shapes, such as Shape<2> SQUARE, Shape<3> CUBE and Shape<3> SPHERE. I might add more predefined Shapes in the future.
I want Shape objects only to be constructible as any of the predefined Shapes. Since the properties of these predefined Shapes 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
Shapecontains all the predefinedShapes (As pointed out in the comments of this question); - Fore every instance of
Shapethat is created, the content of the predefinedShapes 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 Shapes to be constructible.
Factory pattern is what you need. It delegates the creation of the instances to another class.
There are multiple way to implement it, you can choose the level of abstraction depending on the complexity of your problem.
Here's a basic example
if you strictly want to use this approach, you can refer to Prototype Pattern