Previous chapter: Chapter 12: Polymorphism: Virtual Functions and Abstract Classes in C++
Operator overloading allows C++ programmers to redefine the behavior of most standard operators (like +, -, ==) when applied to user-defined types (classes). This makes working with objects intuitive and readable.
1. Operator Overloading: Making Classes Intuitive
The goal of overloading is to make class syntax resemble built-in types. For example, we can make two Vector objects add together using the standard + symbol.
Overloading Binary Operators (e.g., +)
To overload an operator, you define a function named operator@ (where @ is the operator symbol).
class Vector {
private:
int x, y;
public:
Vector(int a, int b) : x(a), y(b) {}
// Overloading the '+' operator
Vector operator+(const Vector& other) const {
return Vector(x + other.x, y + other.y);
}
};
int main() {
Vector v1(1, 2);
Vector v2(3, 4);
Vector v3 = v1 + v2; // Calls v1.operator+(v2)
// v3 is now (4, 6)
return 0;
}
Overloading Unary Operators (e.g., ++)
Unary operators only work on one operand.
class Counter {
// ...
public:
// Overloading the Prefix Increment Operator (e.g., ++c)
Counter& operator++() {
// logic to increment internal value
return *this; // Returns a reference to the modified object
}
// ...
};
2. Overloading Stream Operators (<< and >>)
The most common and useful overloads are the stream insertion (<<) and extraction (>>) operators, which allow your objects to be used seamlessly with std::cout and std::cin. These are typically implemented as non-member functions.
// Non-member function signature for cout (insertion)
std::ostream& operator<<(std::ostream& os, const Vector& v) {
os << "Vector(" << v.x << ", " << v.y << ")";
return os;
}
3. Friend Functions and Friend Classes
A challenge with non-member operator functions is accessing private data members (like v.x and v.y).
A friend function is a non-member function that is granted special permission to access the private and protected members of a class. The declaration is done inside the class definition, prefixed with the keyword friend.
class Vector {
private:
int x, y;
// Grant access to the output operator function
friend std::ostream& operator<<(std::ostream& os, const Vector& v);
public:
Vector(int a, int b) : x(a), y(b) {}
// ...
};
Similarly, a friend class grants all its member functions access to the private and protected members of the class declaring the friendship.