Learning materials
Operator Overloading
On this page
Syntax
Assumptions: a and b are operands; @ is the placeholder for the operator, not the @ operator
Operator Overloading Syntax
| Expression | As method | As function |
|---|---|---|
@a |
(a).operator@() |
operator@(a) |
a@b |
(a).operator@(b) |
operator@(a, b) |
-
Operators that can be overloaded
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= && || ++ -- , ->* ->
Operator overloading as methods
- Only when
ais a class-typed object - Declare as a method in the class of the object
a - Declare as
constmethod to makeaconst - Declare
bas a const formal parameter to makeb
class Point {
int x;
int y;
public:
Point()=default;
Point(int x, int y): x(x), y(y) {}
Point operator+(const Point& other) const {
return Point(x + other.x, y + other.y);
}
// binary - operator
Point operator-(const Point& other) const {
return Point(x - other.x, y - other.y);
}
// Unary - operator
Point operator-() const {
return Point(-x, -y);
}
// better to make it const! Check the warning after
bool operator==(const Point& other) const {
return x == other.x && y == other.y;
}
void print() const {
cout << "X: " << x << " Y: " << y << endl;
}
};
int main() {
Point p1(10, 5), p2(2, 1);
Point p3 = p1 + p2;
Point p4 = p1 - p2;
p3.print();
(-p3).print();
p4.print();
if (p1 == p2) cout << "P1 equals P2" << endl;
else cout << "P1 not equal P2" << endl;
return EXIT_SUCCESS;
}
Operator overloading as functions
aandbcan be any type- Declare
aandbas a const formal parameters to make them const - may be declared as a
friendfunction of a class to access private instance variables
class Point {
int x;
int y;
public:
Point()=default;
Point(int x, int y): x(x), y(y) {}
void print() const {
cout << "X: " << x << " Y: " << y << endl;
}
// binary +
friend Point operator+(const Point& p1, const Point & p2) {
// will need public getter for x and y if not defined as a friend method
// return Point(p1.getX() + p2.getX(), p1.getY(), p2.getY()
return Point(p1.x + p2.x, p1.y + p2.y);
}
// binary -
friend Point operator-(const Point& p1, const Point & p2) {
return Point(p1.x - p2.x, p1.y - p2.y);
}
// Unary - operator
friend Point operator-(const Point &p1) {
return Point(-p1.x, -p1.y);
}
friend bool operator==(const Point& p1, const Point & p2) {
return p1.x == p2.x && p1.y == p2.y;
}
};
int main() {
Point p1(10, 5), p2(2, 1);
Point p3 = p1 + p2;
Point p4 = p1 - p2;
p3.print();
(-p3).print();
p4.print();
if (p1 == p2) cout << "P1 equals P2" << endl;
else cout << "P1 not equal P2" << endl;
return EXIT_SUCCESS;
}
Const
It is a great practice to make everything const if possible. For instance, operators like arithmetic, relational, logical operators can usually be made const. Some operators like ++/--, =, +=, etc. cannot be const as they must modify the internal state of the object.
Best Practice
Do not abuse operator overloading. Only use it when it is logically making sense. Anything that may surprise the user should be avoided.