使用模板
编写代表1D,2D,3D点的类是否值得template <class T>
class Point2D
{
protected:
T X, Y;
public:
Point2D(const T x, const T y) : hot smileyx), Y(y)) {}
...
};
template <class T>
class Point3D : public Point2D<T>
{
protected:
T Z;
public:
Point3D(const T x, const T y, const T z) : Point2D<T>(x,y), Z(z) {}
...
};
......或使用这种方法:
class Point2D
{
protected:
double X, Y;
public:
Point2D(const double x, const double y) : X(x), Y(y)) {}
...
};
class Point3D : public Point2D
{
protected:
double Z;
public:
Point3D(const double x, const double y, const double z) : Point2D(x,y), Z(z) {}
...
};
我们将坐标理解为连续变量,因此使用double值表达它们是有意义的。使用矩阵时会出现类似的情况。但是在这种情况下,模板被广泛使用......
这个课程不仅供一次性使用,而且还是图书馆的一部分......以及我的第二部分问题。如何实施某些“衡量”功能?
template <class T>
T getDist(const Point2D <T> * p1, const Point2D<T> *p2)
{
....
}
或
double getDist(const Point2D <T> * p1, const Point2D<T> *p2)
{
....
}
一般地或某些特定类型写这样的函数是否合理?
答案 0 :(得分:6)
为什么重复自己?这些类和函数的大部分内容都是相同的。
这样的事情效果更好:
template <std::size_T N, typename T>
class Point
{
public:
Point()
{
std::fill_n(mData, N, T());
}
explicit Point(const T& pX) :
mData[0](pX)
{
// or some variant (enable_if also works)
static_assert(N == 1, "X constructor only usable in 1D");
}
explicit Point(const T& pX, const T& pY) :
mData[0](pX),
mData[1](pY),
{
static_assert(N == 2, "XY constructor only usable in 2D");
}
// incomplete, left as exercise for reader. :P
private:
T mData[N];
};
你只需使用循环来实现这些功能:
template <std::size_T N, typename T>
T getDist(const Point<N, T>& pFirst, const Point<N, T>& pSecond)
{
// generic, compiler will unroll loops
}
答案 1 :(得分:2)
根据我的经验,我会避免像瘟疫一样创建一个3D点 IS-A 2D点的类层次结构。这使得3D点非常容易被无意中和无声地视为2D点。最好保持不同维度的坐标不同类型(根据GMan的答案)并要求类型之间明确强制。
我目前最喜欢的这种事情的实现是由Eigen提供的。即使它的许可证(LGPL)限制它对你的使用,我建议你看一下优雅模板化的矢量和矩阵类型并从中学习。
答案 2 :(得分:1)
如果所有功能都正确有效地实现,对我来说似乎没问题。对于距离测量:
template <class T>
T getDist(const Point3D <T>& p1, const Point3D<T>& p2);
应该使用签名。距离也可以是3D。
答案 3 :(得分:1)
我遇到了这种情况,并且有理由允许X和Y值使用不同的类型,其中X有时是整数但Y总是具有更高的精度(浮点数或双精度取决于使用情况)。可能值得考虑前期。
答案 4 :(得分:0)
还应该考虑如何使用课程。你提到了矩阵。如果您计划使用该类或其他任何包含矩阵反转(或其他类似矩阵运算)的系统来解决系统,将矩阵表示为一堆整数将是非常古怪的。
如果你计划将它简单地用作一个排序表(或者只是添加/减去并乘以矩阵),那么你可以模拟该类,因为一个完整的整数矩阵不会提供奇怪的(和不正确的)这些行动的结果。