Give user-defined values familiar operations
Operator overloading lets a class participate in expressions such as a+b when that operation has a clear meaning. It cannot create new operator symbols, change precedence or change the number of operands. At least one operand of an overloaded operator must have a user-defined or enumeration type.
A two-dimensional displacement value
#include
struct Displacement {
int x{0};
int y{0};
Displacement& operator+=(const Displacement& other) {
x += other.x;
y += other.y;
return *this;
}
};
Displacement operator+(Displacement left, const Displacement& right) {
left += right;
return left;
}
std::ostream& operator<<(std::ostream& out, const Displacement& value) {
return out << '(' << value.x << ", " << value.y << ')';
}
int main() {
Displacement a{2, 3}, b{4, -1};
std::cout << a + b << '\n';
std::cout << a << '\n';
} Expected lines: (6, 2) and (2, 3). Addition returns a new value, leaving a unchanged. The += operator modifies its left operand and returns a reference so chained compound assignments behave naturally. Inputs here are small; production arithmetic must also address overflow.
Why output insertion returns the stream
Returning std::ostream& permits out << first << second. The left operand is a stream rather than your class, so a free function is a natural choice. Do not return a reference to a local temporary result from operator+; it would dangle after the function returns.
Preserve expected meaning
Users expect + to represent a value-combining operation and == to represent equality. Surprising side effects make code harder to reason about. Overloading && or || as ordinary function-call operators does not provide the usual short-circuit behavior expected from built-in logical expressions; avoid that design for ordinary value classes.
Member versus non-member
A non-member binary operator can support symmetric conversions on both sides. A member has an implicit left-hand object. Choose the design that describes the operation rather than making every operator a friend automatically. Keep representation private when the type has invariants that must be protected.
Exercises
- Add operator- for Displacement. With the sample values, a-b should be (-2, 4).
- Implement equality by comparing both coordinates.
- Why must operator+ return by value rather than reference to its local left parameter?
- Can overloading + change the meaning of 2+3? No: both operands are built-in types.