0

我正在开发一个程序来检测一个三角形是否嵌套在另一个三角形中。

在这里,我创建了结构点来将 x 和 y 定义为双精度。

struct Point {

double  x;
double  y;
};

这是我实现结构的地方:

double eval (LineSegment line, Point p)
{

 Point p1 = p - line.StartPoint;
 Point p2 = line.EndPoint - line.StartPoint;

 return p2.x * p2.y - p1.y * p2.x;


}

当我编译它告诉我,“'p - line.LineSegment::StartPoint'中的'operator-'不匹配。” 我真的不明白发生了什么,我想它不明白我想要哪个“点”,因为我一起使用它们?

我做了研究,发现运算符重载,但这让我有点困惑。我真的不知道如何实现运算符重载。

如果有人能告诉我如何去做这件事,那将会很有帮助。

4

6 回答 6

9

这意味着编译器不知道如何减去Point对象。它知道如何减去内置类型,但是要使用自定义类型的运算符,您需要提供行为。

在这种情况下,您可能需要以下内容:

struct Point
{
   double  x;
   double  y;

   Point& operator-=( const Point& that )
   {
      x -= that.x;
      y -= that.y;
      return this;
   }
};

Point operator-(Point first, const Point& second)
{
    return first -= second;
}

有关更多指导,请参阅我们关于运算符重载的 C++-FAQ 条目。那里有很多好的建议可以帮助您避免一些陷阱,以及如何最大限度地提高代码重用性和可读性(这实际上意味着可维护性)的好例子和建议。

在这种情况下,您还应该问自己是否要区分绝对坐标对和相对坐标对。如果你这样做,那么两点之间的差异应该是 aSizeOffset,而不是 a Point。(如果您曾经使用过带有DateTimeTimeSpan类的库,那么您已经看到了这个概念的实际应用。C++ 本身将它用于标准库的time_pointvs duration,两者都在 namespace 中std::chrono。您在这里有一个二维版本。)

于 2013-09-11T18:23:18.530 回答
2
struct Point {
    double  x;
    double  y;

    Point operator-(const Point& that) const
    {
       Point result;
       result.x = this->x - that.x;
       result.y = this->y - that.y;
       return result;
    }
};
于 2013-09-11T18:23:04.217 回答
2

如果你想减分,那么你需要提供一个重载的运算符来做。C++ 不会自动为类类型生成算术运算,因为大多数时候它们没有意义。

这样的事情应该这样做:

Point operator-(Point lhs, Point rhs) {
    return {lhs.x-rhs.x, lhs.y-rhs.y};
}

尽管我可能会为返回类型引入一种新类型(VectorOffset其他类型),以防止在您应该使用点时使用点之间的偏移量的类别错误。

于 2013-09-11T18:24:39.487 回答
1

这是一个让您入门的基本草图:

Point operator-( const Point& lhs, const Point& rhs )
{
    Point result;
    // make sure this is what you want:
    result.x = lhs.x - rhs.x;
    result.y = lhs.y - rhs.y;
    return result;
}

请注意,这是一个免费功能,它不在Point' 定义内。只是放在后面。

于 2013-09-11T18:23:37.293 回答
1

看看http://www.cplusplus.com/doc/tutorial/classes2/。它对运算符重载有很好的解释。

您的代码所说的是从 p 中减去 line.StartPoint。但是,您的结构没有为该操作定义的行为。p - line.StartPoint因此,除非您告诉编译器如何使用您的结构执行该操作,否则您不能使用该语法。

结构中的方法签名可能如下所示:

Point operator-(const Point &other) { }

您需要向该方法添加逻辑,告诉编译器如何对您的结构执行减法运算。

于 2013-09-11T18:24:44.283 回答
0

如果您将两个数字加/减/乘...等在一起,编译器就会知道您的意思,一切都很好。如果您想减去某个类的内容,编译器本身并不知道如何执行此操作(对于任何类),但为您提供了一个工具来定义如何将两个类相减,它看起来像这样(使用您的 Point 类) :

    Point operator-(Point p1, Point p2)
    {
         Point result;
         result.x = p1.x - p2.x;
         result.y = p1.y - p2.y;
         return result;
    }

现在编译器知道如何通过调用这个函数减去两个点。

于 2013-09-11T18:24:28.720 回答