使用2D / 3D点模板

时间:2010-10-14 20:30:33

标签: c++ templates

使用模板

编写代表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)
{
....
}

一般地或某些特定类型写这样的函数是否合理?

5 个答案:

答案 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)

还应该考虑如何使用课程。你提到了矩阵。如果您计划使用该类或其他任何包含矩阵反转(或其他类似矩阵运算)的系统来解决系统,将矩阵表示为一堆整数将是非常古怪的。

如果你计划将它简单地用作一个排序表(或者只是添加/减去并乘以矩阵),那么你可以模拟该类,因为一个完整的整数矩阵不会提供奇怪的(和不正确的)这些行动的结果。