我想要一个类模板template<std::size_t N> Shape
,其中模板参数N
代表Shape
的尺寸。应该有数量有限的预定义Shape
,例如Shape<2> SQUARE
,Shape<3> CUBE
和Shape<3> SPHERE
。我将来可能会添加更多预定义的Shape
。
我希望Shape
对象只能像任何预定义的Shape
一样构造。由于这些预定义的Shape
的属性始终保持不变,因此最好将它们仅存储一次,并让新的Shape
对象引用它们。
此刻,我有以下实现:
// 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}});
此实现存在一些问题:
Shape
的每个实例都包含所有预定义的Shape
(如this question的注释中所述); Shape
的每个实例,都将复制预定义的Shape
的内容; Shape<3>
对象也包含Shape<2> SQUARE
。我想知道哪种更好的设计模式来实现上述目标。
我当时在考虑使用Tag
作为构造函数参数,并使用某种工厂。但是,由于模板的复杂性以及我只希望预定义的Shape
是可构造的,因此我难以正确地实现实现细节。
答案 0 :(得分:1)
工厂模式是您所需要的。它将实例的创建委托给另一个类。
有多种实现方式,您可以根据问题的复杂程度选择抽象级别。
这是一个基本示例
template<std::size_t N>
class Shape
{
friend class ShapeFactory;
public:
// 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} {};
};
class ShapeFactory
{
public:
// return value optimization
static Shape<3> createSphere()
{
return Shape<3>(Tag::SPHERE, 3.0,{{0.0,2.7,0.0,2.7,0.0,2.7}});
}
static Shape<3> createCube()
{
return Shape<3>(Tag::CUBE, 1.0,{{0.0,1.0,0.0,1.0,0.0,1.0}});
}
static Shape<2> createSquare()
{
return Shape<2>(Tag::SQUARE, 1.0,{{0.0,1.0,0.0,1.0}});
}
};
由于这些预定义形状的属性完全相同 时间,最好只将它们存储一次,并具有 新的Shape对象引用了它们。
如果您严格希望使用此方法,则可以参考原型模式