类似类型的设计

问题描述 投票:1回答:1

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

EG

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
};

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

我想避免/最小化代码重复,因此使用模板似乎是一种自然的方法。无论如何,我希望我的类看起来像普通的类,而不是模板化的类(一个选项是从模板化的类派生;另一个是类型化类的特化)。

此外,还有一个令人讨厌的约束:并非所有方法对所有数据类型都有意义,并且在某些类中根本不应该声明,或者可能存在某些参数类型的特殊情况。

在我的尝试中,我遇到了许多问题,例如需要添加许多显式实例化,难以避免无意义的成员,在基础/派生类之间转换问题......使整个设计变得痛苦。总而言之,我花了更多的代码来编写模板而不是没有!

您是否经历过类似的课程设计?有没有经典的方法来解决这个问题?

c++ oop inheritance class-design
1个回答
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是一个模板类型,它为返回的提供的整数类型返回正确大小的浮点类型。

© www.soinside.com 2019 - 2024. All rights reserved.