C++ Operator Overloading
Operator overloading lets your own types use operators like built-in types: add two vectors with +, compare two dates with <, print an object with <<. An overloaded operator is simply a function with a special name, such as operator+.
Arithmetic and printing
ExampleTry it in the editor
#include <iostream>
struct Vec2 {
double x = 0, y = 0;
Vec2 operator+(const Vec2& o) const { return {x + o.x, y + o.y}; }
Vec2 operator*(double k) const { return {x * k, y * k}; }
Vec2& operator+=(const Vec2& o) { x += o.x; y += o.y; return *this; }
bool operator==(const Vec2& o) const { return x == o.x && y == o.y; }
};
std::ostream& operator<<(std::ostream& os, const Vec2& v) {
return os << "(" << v.x << ", " << v.y << ")";
}
int main() {
Vec2 a{1, 2}, b{3, 4};
std::cout << a + b << "\n";
std::cout << a * 3 << "\n";
a += b;
std::cout << a << "\n";
std::cout << std::boolalpha << (a == Vec2{4, 6}) << "\n";
return 0;
}Output
(4, 6) (3, 6) (4, 6) true
- A member operator takes the right-hand value as its parameter; the left-hand value is the object itself.
operator<<must be a free function (its left side is the stream), and it returns the stream so outputs can be chained.- Compound operators like
+=change the object and return*thisby reference.
Comparison
To sort objects or use them in a std::set or as std::map keys, define operator<. C++20 can generate all six comparisons from one line, the "spaceship" operator <=>:
ExampleTry it in the editor
#include <algorithm>
#include <compare>
#include <iostream>
#include <vector>
struct Version {
int major, minor;
auto operator<=>(const Version&) const = default; // compares major, then minor
};
int main() {
std::vector<Version> v = {{2, 1}, {1, 9}, {2, 0}};
std::sort(v.begin(), v.end());
for (const auto& x : v) std::cout << x.major << "." << x.minor << " ";
std::cout << "\n" << std::boolalpha << (Version{1, 9} < Version{2, 0}) << "\n";
return 0;
}Output
1.9 2.0 2.1 true
Guidelines
- Overload an operator only when its meaning is obvious:
+for adding vectors or money,<for ordering.a + bshould never delete a file. - Keep related operators consistent: if you define
+, define+=too; if you define==, the meaning of!=follows (C++20 generates it). - Prefer
const¶meters and mark operators that do not change the objectconst. - Some operators cannot be overloaded, such as
.,::and?:. - Implement
+=as a member first, then write+using it, so the logic lives in one place. - Define
operator<<as a free function takingstd::ostream&and returning it, so output can be chained.
Practice exercises
- Write a
Moneytype with rupees and paise and overload+and<<. - Give a
Fractiontype*,==and<<. - Sort a vector of
Datestructs with the spaceship operator.