5

When a class overloads operator+, should it be declared const since it does not do any assignment on the object? Also, I know that operator= and operator+= return a reference because an assignment is made. But, what about operator+? When I implement it should I make a copy of the current object, add the given object to that, and return that value?

Here is what I have:

class Point
{
public:
    int x, int y;

    Point& operator += (const Point& other) {
        X += other.x;
        Y += other.y;
        return *this;
    }

    // The above seems pretty straightforward to me, but what about this?:
    Point operator + (const Point& other) const { // Should this be const?
        Point copy;
        copy.x = x + other.x;
        copy.y = y + other.y;
        return copy;
    }
};

Is this a correct implementation of the operator+? Or is there something I am overlooking that could cause trouble or unwanted/undefined behavior?

Brandon Miller
  • 2,247
  • 8
  • 36
  • 54
  • 1
    Many details of operator overloading can be found here: http://stackoverflow.com/questions/4421706/operator-overloading – chris Nov 16 '12 at 05:13

1 Answers1

6

Better than that, you should make it a free function:

Point operator+( Point lhs, const Point& rhs ) { // lhs is a copy
    lhs += rhs;
    return lhs;
}

But yes, if you leave it as a member function it should be const as it does not modify the left hand side object.

Regarding whether to return a reference or a copy, the advice for operator overloading is do as fundamental types do (i.e. do as ints do). In this case, addition for two integers returns a separate integer that is not a reference to neither one of the inputs.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • Ah, I see. Thank you. Also, what is the benefit of having it as a free function? – Brandon Miller Nov 16 '12 at 05:15
  • 1
    @BrandonMiller: Symmetry respect to types. If your type has an implicit conversion constructor (i.e. can be implicitly converted from some other type), the free function implementation will allow conversions on both arguments, while the member function can only do conversions on the right hand side. – David Rodríguez - dribeas Nov 16 '12 at 05:17
  • Also, if I overload `operator<`, should I make the return type a bool? So `ptA < ptB` will evaluate to true or false? It seems like it should be obvious, but I am not so sure. – Brandon Miller Nov 16 '12 at 05:25
  • @BrandonMiller: Go with the obvious. – Fred Larson Nov 16 '12 at 05:30
  • @BrandonMiller: What other options are there? Comparisons are either true or false, the type that has that range is `bool`. – David Rodríguez - dribeas Nov 16 '12 at 05:31
  • @DavidRodríguez-dribeas Apologies for trying to be absolute, I was looking at an article about operator overloading which showed the prototype as `R T::operator < (S b);`, the rest said nothing about it positively having to be a bool. – Brandon Miller Nov 16 '12 at 05:34
  • @BrandonMiller It doesn't have to be `bool`. – Luc Danton Nov 16 '12 at 05:40
  • @LucDanton: It doesn't **have** to be a `bool`, but it **should** following the principle of least surprise. You can even define it with a `void` return type from the language standpoint, but that does not mean that it makes any sense. Defining it to return anything other than `bool` is allowed but not recommended --there will be some corner case where it will cause surprises. – David Rodríguez - dribeas Nov 16 '12 at 16:39
  • And, in parallel with `operator+` using `operator+=`, it's often useful to have a member `compare` that returns a negative value for less than, zero for equal, or positive for greater than. `operator<` can then be a non-member function that calls the member `compare`. – Pete Becker Nov 16 '12 at 17:17