相似类型类的设计

时间:2019-04-24 17:17:37

标签: c++ oop inheritance class-design

我正在设计代表矢量等几何对象的类。我需要定义诸如加法,标量乘法,点积和其他方法。向量坐标可以是不同大小的整数或实数,因此需要复制对应于这些不同类型的类。

例如

class intVector
{
   int X, Y;

   intVector& operator+=(const intVector& A) { … }
   intVector& operator*=(int A) { … }

   float Norm(); // Not int
};

class floatVector
{
   float X, Y;

   floatVector& operator+=(const floatVector& A) { … }
   floatVector& operator*=(float A) { … }

   float Norm(); // Would be double for a doubleVector
};

(我还需要将二进制运算符定义为函数而不是方法。)

我想避免/减少代码重复,因此使用模板似乎是一种自然的方法。无论如何,我希望我的类显示为普通类,而不是模板化类(一种选择是从模板化类派生;另一种是typedef类专业化)。

此外,还有一个讨厌的约束:并非所有方法对所有数据类型都有意义,并且某些类中的所有方法都不应该完全声明,否则某些参数的类型可能会有特殊情况。

在尝试过程中,我遇到了许多问题,例如需要添加许多显式的实例化,难以避免没有意义的成员,在基类/派生类之间转换问题……使整个设计痛苦不堪。总而言之,与没有模板相比,我用模板编写的代码更多!

您经历过类似的课堂设计吗?有经典的解决方法吗?

1 个答案:

答案 0 :(得分:1)

模板是处理此问题的正确方法。您可以做的是为需要以不同方式运行的不同函数添加重载,并使用SFINAE将重载约束为所需的类型。使用模板,我们可以将两个类组合成一个通用的Vector类,然后使用type alias来获取不同类型的具体名称。看起来像

template<typename T>
class Vector
{
   T X, Y;

   Vector& operator+=(const Vector& A) { … }
   Vector& operator*=(T A) { … }

   template<typename U = T, std::enable_if_t<std::is_integral_v<U>, bool> = true>
   correct_size_floating_point_type<U> Norm() { integer code } 
   template<typename U = T, std::enable_if_t<std::is_floating_point_v<U>, bool> = true>
   U Norm() { floating point code }
};

using intVector = Vector<int>;
using floatVector = Vector<float>;

correct_size_floating_point_type是一种模板类型,它为提供的整数类型返回正确大小的浮点类型。