【问题标题】:Making a Point class in c++在 C++ 中创建一个 Point 类
【发布时间】:2009-04-30 22:05:46
【问题描述】:

现在我正在使用 std::pair 来表示 C++ 中的二维点。但是,我对不得不写作感到恼火

typedef std::pair<double, double> Point;

Point difference = Point(p2.first - p1.first,
                         p2.second - p1.second);

而不是能够重载 operator+ 和 operator-。

所以,我的问题是,要让我的 Point 类,我应该

  • 公开派生自 std::pair 并添加我自己的成员函数?这很好,因为我所有的代码都可以保持不变。我不会做像std::pair&lt;double, double&gt;* p = new Point; 这样的事情,所以我不必担心虚拟析构函数之类的事情。
  • 滚动我自己的 Point 类,这很烦人,因为我正在复制 std::pair 的功能,但我是“以纯粹的方式做”。
  • 为 std::pair 制作 operator+ 和 operator- 的模板特化,诚然我不记得它们是放在源文件还是头文件中。

我想这是有争议的,我真的很想做#1,但我不知道这是不是一个坏主意,因为我听说从 STL 继承是一个禁忌。

【问题讨论】:

  • 仅供参考——从 STL 继承的原因是禁忌,因为它没有虚拟析构函数。因此,如果您通过指向 STL 基类型的指针删除了自己的类,则不会调用您的析构函数。
  • 我说过我不会在问题中那样做。
  • 没想到你会;只是认为提供原因会有所帮助。

标签: c++ inheritance operator-overloading


【解决方案1】:

您可以滚动自己的 Point 类,但在内部使用 std::pair 来存储数据。这可以防止从 STL 问题继承,但仍然使用 std::pair 的功能。

【讨论】:

  • +1。如果您碰巧阅读了 Code Complete,它建议了这种确切的做法:如果 [the class Point] is a [std::pair],则继承。否则,[std::pair] 应存储为私有成员,而 [Point] 应改为定义自己的接口。 “point.first”没有意义; point.x 可以。
  • 这可能就是我的灵感来源。那本书很震撼!
  • 我明白为什么从stl::pair 继承不好;但是为什么首先要使用stl::pairstl::pair 的哪些特性与 Point 相关?也许我遗漏了一些明显的东西,但是订购,swapget,各种构造函数似乎都与Point无关。
【解决方案2】:

比自己动手更好:获取现有的免费矢量/点库。一个推荐:附在Essential Math for Games Programmers的那个。您可以使用您找到的任何库作为起点,然后从那里优化/专门化/调整。

【讨论】:

    【解决方案3】:

    如果您想使用 std::pair 的功能,我会支持创建您自己的 Point 类并使用私有继承或组合。 typedef 的问题(我相信您知道)是您编写的任何采用 Point 的函数也可以被表示为 std::pair 的任何东西使用,这可能是无效的。

    考虑到这一点,存在另一种选择,即创建一些免费的构建器函数,例如

    Point addPoints(const Point& p1, const Point& p2);
    Point diffPoints(const Point& p1, const Point& p2);
    

    (函数名可能更好)。

    【讨论】:

      【解决方案4】:

      另一种选择可能是让您拥有 Point 类,并让您的类“拥有”代表点坐标的 std::pair。

      很多时候,“HAS A”(组合)关系优于“IS A”(继承)关系。

      【讨论】:

        【解决方案5】:

        我认为“最佳实践”会说推出您自己的 Point 课程。通过这种方式,您可以更轻松地制作 3D。

        【讨论】:

        • 绝对不需要 3d。是为了游戏。 2d 游戏。
        【解决方案6】:

        私有继承又名实现继承,是你的朋友。

        这在逻辑上如下:a Point 不是 std::pair,您不希望从 Point 到 std::pair 进行公共向上转换,但您确实想使用 std::pair 的内部结构。

        另一种可能性是 has-a 关系或组合:每个 Point 都有一个它在内部使用的私有 std::pair。

        事实上,组合继承和私有继承并没有太大区别,只是在后者中,您可以在 Point 成员函数中强制向上转换为 std::pair。

        【讨论】:

          【解决方案7】:

          滚动你自己的 Point 类。这将允许您在将来用它做任何事情。具体来说,我以前解决过这类问题,我发现有用的是定义我自己的Point结构,并创建一个继承自它的Point类。

          完全披露:我不太喜欢 STL。

          【讨论】:

            【解决方案8】:

            不要从 std::pair 公开继承,因为 std::pair 有一个运算符

            【讨论】:

              猜你喜欢
              • 2017-05-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-10-15
              相关资源
              最近更新 更多