askque
askque

Reputation: 319

const qualifier end of function

#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

Answers (4)

Walter
Walter

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

Fox
Fox

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

The only problem is "const" Point operator+(const Point & rhs); remove that in the def and dec .. it will work

Upvotes: 0

Jean-Baptiste Yun&#232;s
Jean-Baptiste Yun&#232;s

Reputation: 36391

You need to define your method as a constone, 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

Related Questions