Operator Overloading
Operator overloading lets you define what operators like +, ==, or << mean for your own class types, so objects of that type can be combined and compared with the same natural syntax as built-in types like int or double.
Member vs. free function
An operator can be overloaded as a member function of the class, or as a free (non-member) function — sometimes declared a friend of the class so it can reach private data.
Situation | Which form to use |
|---|---|
Left operand is always your class (e.g. | Member function works well: |
Left operand is not your class (e.g. | Must be a free function — the left operand ( |
Operator needs access to private data but isn't naturally a member | Free function declared |
A worked example: Vector2D
Overloading +, ==, and << for a 2D vector
#include <iostream>
class Vector2D {
public:
double x, y;
Vector2D(double x = 0, double y = 0) : x(x), y(y) {}
// Member function: left operand is always a Vector2D, so this works well.
Vector2D operator+(const Vector2D& other) const {
return Vector2D(x + other.x, y + other.y);
}
bool operator==(const Vector2D& other) const {
return x == other.x && y == other.y;
}
// Free function needs access to private data here, but x/y are public,
// so no 'friend' declaration is required in this particular example.
friend std::ostream& operator<<(std::ostream& out, const Vector2D& v);
};
// Free function: left operand is std::ostream, not Vector2D.
std::ostream& operator<<(std::ostream& out, const Vector2D& v) {
out << "(" << v.x << ", " << v.y << ")";
return out; // return the stream so calls can be chained: cout << a << b
}
int main() {
Vector2D a(1, 2);
Vector2D b(3, 4);
Vector2D sum = a + b; // uses operator+
bool same = (a == b); // uses operator==
std::cout << "a = " << a << "\n"; // uses operator<<
std::cout << "sum = " << sum << "\n";
std::cout << "a == b? " << same << "\n";
}Keep overloads intuitive
What's next
The
frienddeclaration used foroperator<<above is explained in full on the next page, Friend Functions & Classes.