起源 - 恒定还是新型?

时间:2013-05-13 11:55:34

标签: c++ c++11 geometry

我正在编写一个Point类(在3d空间中)并且一直想知道创建原点的最佳方法是什么。这是基本类(取自Andy的例子,以防有人想知道基本实现是什么):

struct Point
{
    constexpr Point(double x_, double y_, double z_) : x(x_), y(y_), z(z_) { }

    double x;
    double y;
    double z;
};

获得原点的第一种方法是定义constexpr变量:

constexpr Point origin = { 0.0, 0.0, 0.0 };

第二种方法是定义一个新类型和重载算法,如果用原点计算它们可以从优化中受益(让我们假设我为constexpr写了一个Point构造函数):

struct Origin: public Point
{
    constexpr Origin():
        Point(0.0, 0.0, 0.0)
    {}
};
constexpr Origin origin;

虽然第一种方法似乎更简单,更不容易出错,但我想知道第二种方法是否是一个好主意,是否有一些我没有看到的陷阱。

编辑:考虑参考库,我注意到CGAL使用了类似的东西:

class Origin {};
const Origin ORIGIN;

1 个答案:

答案 0 :(得分:6)

  

虽然第一种方法似乎更简单,更不容易出错,但我想知道第二种方法是否是一个好主意,是否有一些我没有看到的陷阱。

我认为基于继承的设计在概念上存在缺陷:你不想在这里引入一个新类型,并且原点在概念上是一个实例(一个非常特殊的实例,但仍然是一个实例) Point类,而不是该类型的特化。

我希望在这里添加名为constexpr的静态origin()成员函数:

struct Point
{
    constexpr Point(double x_, double y_, double z_) : x(x_), y(y_), z(z_) { }
    constexpr static Point origin() { return {0, 0, 0}; }

    double x;
    double y;
    double z;
};

然后您可以这样使用:

int main()
{
    constexpr Point o = Point::origin();
}

或者,您可以添加名为Point的{​​{1}}类型的静态数据成员,而不是使用名为origin的静态函数。选择哪一个主要是品味问题。