我需要创建一个描述一组数学形状的类。假设我想要 Sphere
、Cylinder
、AABB
和 OBB
。对于这些,我将创建一个 enum
来表示它们,并希望用户传递他们所需的形状类型并提供正确的输入。例如:
// Shapes.h
enum ShapeType { Sphere, Cylinder, AABB, OBB, Count};
class Shape {
public:
Shape(ShapeType type, const float r, const float hl, const Vector3& minExtend, const Vector3& maxExtend);
private:
ShapeType m_Type;
float m_Radius; // for Sphere and Cylinder end caps
float m_halfLength; // for Cylinders
Vector3 m_minExtend; // for AABB or OBB
Vector3 m_maxExtend; // for AABB or OBB
Entity m_Parent; // has position, orientation and scale;
}
不理想的是,在创建 Shape
实例时,用户被迫提供所有变量,即使他们不需要。例如,Sphere 不会关心半长。因此我的问题是 - 有没有一种方法可以根据 enum
值专门化我的构造函数?例如下面的伪代码:
// Shapes.h
enum ShapeType { Sphere, Cylinder, AABB, OBB, Count};
class Shape {
public:
Shape(ShapeType type = Sphere, const float r);
Shape(ShapeType type = Cylinder, const float r, const float hl);
Shape(ShapeType type = AABB, const Vector3& minExtend, const Vector3& maxExtend);
Shape(ShapeType type = OBB, const Vector3& minExtend, const Vector3& maxExtend);
// ... same as above
注意,我真的不想在这里使用继承并创建一系列形状,因为此类实际上只是用于在发送到另一个进程之前保存一些原始数据。
最佳答案
如果您提供形状类型作为参数,则无法执行此操作。毕竟给了
float r = 5;
ShapeType shape = getRandomShape(); // determine the shape to use via random number generation
Shape shape(shape, r);
编译器无法判断shape
是否为ShapeType::Sphere
;该值在运行时确定。
如果您始终直接提供常量,则可以通过使用maker参数来实现与此类似的效果,为编译器提供具有ShapeType
类型的模板参数的对象,以便能够确定使用重载解析正确的构造函数。
template<ShapeType>
struct ShapeTypeTag
{};
inline constexpr ShapeTypeTag<ShapeType::Sphere> SphereType;
class Shape {
public:
Shape(ShapeTypeTag<Sphere>, const float r);
Shape(ShapeTypeTag<Cylinder>, const float r, const float hl);
Shape(ShapeTypeTag<AABB>, const Vector3& minExtend, const Vector3& maxExtend);
Shape(ShapeTypeTag<OBB>, const Vector3& minExtend, const Vector3& maxExtend);
};
...
Shape shape(SphereType, 5);
我首选的实现方法是在 Shape
中创建单独的静态成员函数来创建每种形状类型:
class Shape {
template<ShapeType>
ShapeTypeTag
{
};
Shape(const float r);
Shape(const float r, const float hl);
Shape(ShapeTypeTag<AABB>, const Vector3& minExtend, const Vector3& maxExtend);
Shape(ShapeTypeTag<OBB>, const Vector3& minExtend, const Vector3& maxExtend);
public:
static Shape createSphere(float r)
{
return r;
}
static Shape createCylinder(float r, float hl)
{
return { r, hl };
}
static Shape createAABB(const Vector3& minExtend, const Vector3& maxExtend)
{
return { ShapeTypeTag<ShapeType::AABB>{}, minExtend, maxExtend };
}
static Shape createOBB(const Vector3& minExtend, const Vector3& maxExtend)
{
return { ShapeTypeTag<ShapeType::OBB>{}, minExtend, maxExtend };
}
};
...
Shape shape = Shape::createSphere(5);
关于c++ - C++ 中基于枚举值的专用类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76792303/