简体   繁体   中英

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.

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'." 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. 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 . 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 . (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.)

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.

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.

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. Just put it afterwards.

Take a look at 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. 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.

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):

    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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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