简体   繁体   English

C ++中的运算符重载(operator-)

[英]Operator overloading in C++ (operator-)

I am working on a program to detect if one triangle is nested within another. 我正在开发一个程序来检测一个三角形是否嵌套在另一个三角形中。

Here I created the struct point to define x and y as doubles. 在这里,我创建了将x和y定义为双精度的结构点。

struct Point {

double  x;
double  y;
};

Here is where I implement the struct: 这是我实现该结构的地方:

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;


}

When I compile it tells me, "no match for 'operator-' in 'p - line.LineSegment::StartPoint'." 当我编译时,它告诉我,“在'p-line.LineSegment :: StartPoint'中没有匹配'operator-'。” I don't really understand what is happening, I guess it doesn't understand which 'point' I want since i use them together? 我真的不了解发生了什么,我想因为我一起使用它们不了解我想要哪个“点”?

I did research and found operator overloading, but it was sort of confusing to me. 我进行了研究,发现运算符重载,但这让我感到困惑。 I don't really know how to implement Operator Overloading. 我真的不知道如何实现操作员重载。

If someone could show me how exactly to go about doing this, it would be helpful. 如果有人可以告诉我如何精确地执行此操作,那将有所帮助。

It means that the compiler has no idea how to subtract Point objects. 这意味着编译器不知道如何减去Point对象。 It knows how to subtract built-in types, but to use operators with custom types, you need to provide the behavior. 它知道如何减去内置类型,但是要对自定义类型使用运算符,则需要提供行为。

In this case you probably want something like: 在这种情况下,您可能想要以下内容:

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;
}

For more guidance, see our C++-FAQ entry on Operator Overloading . 有关更多指导,请参阅关于运算符重载的C ++-FAQ条目 Lots of good advice in there that will help you avoid some of the pitfalls, as well as good examples and recommendations how to maximize code re-use and readability (which really means maintainability). 那里有很多好的建议,可以帮助您避免一些陷阱,以及如何最大化代码重用性和可读性(这实际上意味着可维护性)的良好示例和建议。

In this case, you should also ask yourself whether you want to differentiate between absolute and relative coordinate pairs. 在这种情况下,您还应该问自己是否要区分绝对坐标对和相对坐标对。 If you do, then the difference between two points should be a Size or Offset , and not a Point . 如果这样做,则两个点之间的差应该是SizeOffset ,而不是Point (If you've ever used a library with DateTime and TimeSpan classes, you've seen this concept in action. C++ itself uses it for the Standard Library's time_point vs duration , both found in namespace std::chrono . You have a two dimensional version of that here.) (如果您曾经在DateTimeTimeSpan类中使用过一个库,那么您已经看到了这个概念的实际效果。C++本身将其用于标准库的time_point vs duration ,两者都在命名空间std::chrono time_point找到。您有一个二维的版本。)

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;
    }
};

If you want to subtract points, then you need to provide an overloaded operator to do it. 如果要减去点,则需要提供一个重载运算符来实现。 C++ doesn't automatically generate arithmetic operations for class types, since most of the time they wouldn't make sense. C ++不会自动为类类型生成算术运算,因为大多数时候它们是没有意义的。

Something like this should do it: 这样的事情应该做到:

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

although I'd probably introduce a new type ( Vector or Offset or something) for the return type, to prevent the category error of using the offset between points when you should use a point. 尽管我可能会为返回类型引入一种新类型( VectorOffset或其他类型),以防止在应该使用点时使用点之间的偏移量的类别错误。

Here's a basic sketch to get you started: 这是入门的基本草图:

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;
}

Note this is a free function, it doesn't go inside of Point 's definition. 请注意,这是一个自由函数,它不在Point的定义之内。 Just put it afterwards. 随便放。

Take a look at http://www.cplusplus.com/doc/tutorial/classes2/ . 看看http://www.cplusplus.com/doc/tutorial/classes2/ It has a pretty good explanation on operator overloading. 它对操作符重载有很好的解释。

What your code is saying is to subtract line.StartPoint from p. 您的代码说的是从p中减去line.StartPoint。 However, your struct doesn't have a defined behavior for that operation. 但是,您的结构没有该操作的已定义行为。 So you can't use the syntax p - line.StartPoint unless you tell the compiler how to perform that operation with your struct. 因此,除非您告诉编译器如何对结构执行该操作,否则不能使用语法p - line.StartPoint

The method signature in your struct will probably look something like this: 结构中的方法签名可能看起来像这样:

Point operator-(const Point &other) { }

You need to add the logic to that method that tells the compiler how to perform a subtraction operation on your struct. 您需要向该方法添加逻辑,以告诉编译器如何在结构上执行减法运算。

If you add/subtract/multiply...etc two numbers together the compiler knows what you mean and everything's fine. 如果将两个数字加/减/乘...等,编译器就会知道您的意思,一切都很好。 If you want to subtract something that's a class, the compiler doesn't inherently know how to do that (for ANY class) but gives you a tool to define how to subtract two classes together and it looks like this (using your Point class): 如果您想减去某个类,则编译器并不固有地知道如何执行此操作(对于ANY类),但是为您提供了一个工具来定义如何将两个类相减,并且看起来像这样(使用Point类) :

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

Now the compiler knows how to subtract two points, by calling this function. 现在,编译器知道如何通过调用此函数减去两点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM