4

我正在写一个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;
4

1 回答 1

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或者,您可以添加一个名为的静态数据成员,origin而不是一个名为 的静态函数origin()。选择哪一个主要是口味问题。

于 2013-05-13T11:59:32.317 回答