Reputation: 319
#include <iostream>
using namespace std;
class Point {
private:
int x, y; // Private data members
public:
Point(int x = 0, int y = 0); // Constructor
int getX() const; // Getters
int getY() const;
void setX(int x); // Setters
void setY(int y);
void print() const;
const Point operator+(const Point & rhs);
// Overload '+' operator as member function of the class
};
int main(int argc, char** argv)
{
Point p1(1, 2), p2(4, 5);
// Use overloaded operator +
Point p3 = p1 + p2;
p1.print(); // (1,2)
p2.print(); // (4,5)
p3.print(); // (5,7)
// Invoke via usual dot syntax, same as p1+p2
Point p4 = p1.operator+(p2);
p4.print(); // (5,7)
// Chaining
Point p5 = p1 + p2 + p3 + p4;
p5.print(); // (15,21)
return 0;
}
// Constructor - The default values are specified in the declaration
Point::Point(int x, int y) : x(x), y(y) { } // Using initializer list
// Getters
int Point::getX() const { return x; }
int Point::getY() const { return y; }
// Setters
void Point::setX(int x) { this->x
= x; } // (*this).x = x; x = x
void Point::setY(int y) { this->y = y; }
// Public Functions
void Point::print() const {
cout << "(" << x << "," << y << ")" << endl;
}
// Member function overloading '+' operator
const Point Point::operator+(const Point & rhs) {
return Point(x + rhs.x, y + rhs.y);
}
I'm studying operator overloading and I don't understand why I get the error.
error: no match for 'operator+' (operand types are 'const Point' and 'Point')
I deleted const
qualifier at the end of the operator+
function on purpose in order to understand it. Can someone explain explicitly why I need it?
Upvotes: 2
Views: 239
Reputation: 45414
The member
const Point Point::operator+(const Point & rhs);
is a non-const member, i.e. requires the lhs of the operation to be mutable, but (as the error message shows) you require an operation with a const
lhs. Hence, you must declare the operator as such
Point Point::operator+(const Point & rhs) const;
Note that I also removed the const
for the return type, as it is deprecated.
Why do you need the const
? The natural +
operator (for example between arithmetic types) does not alter its arguments and, as a consequence, the usual (human) conventions for using this operator implicitly assume that the arguments are not altered. In your particular case, the return of a+b
was explicitly const
(though that is deprecated AFAIK), so that in a+b+c
= (a+b)+c
the lhs is const
and your non-const member function cannot be used.
Moreover, whenever a member function does not alter the state of its object, it should be declared const
, so that it can be called for const
object.
Alternatively, this operator can be defined as non-member function friend
Point operator+(const Point&lhs, const Point&rhs);
which more clearly expresses the symmetry between lhs and rhs (the corresponding function for your non-const member would have been
Point operator+(Point&lhs, const Point&rhs);
).
Upvotes: 2
Reputation: 2138
Good answers, but they don't explain why the const is an issue. The simple reason is chaining order and operator type matching.
Point p5 = p1 + p2 + p3 + p4;
// is interpreted as:
Point p5 = ConstPoint( (Point(p1)).operator+((const Point&)(p2)) + p3 + p4;
// as operator+ is left-to-right , not right-to-left !!!
Point and const Point are different types, so in the first iterpretation, you have a:
p5 = const Point(sumP1P2) . operator+ (Point(P3)) /*+ P4 awaiting interpretation */;
// whose search will be for a const LHS - i.e. "Point operator=(constPointRef) const;" - which is bound to fail.
The following will work:
const P& operator+(const P& rhs) const; // corresponds to const P& result = const P& lhs + const P& rhs
P operator+(P rhs) const; // corresponds to copy-by-value for all operands.
Upvotes: 1
Reputation: 9
The only problem is "const" Point operator+(const Point & rhs); remove that in the def and dec .. it will work
Upvotes: 0
Reputation: 36391
You need to define your method as a const
one, i.e.:
const Point operator+(const Point & rhs) const;
p1+p2
returns a const Point
so you need a const Point + const Point
operator to be able to compute (p1+p2)+p3
.
Upvotes: 1