Operator Overloading in C++
Learn operator overloading in C++ to customize arithmetic, comparison, and other operators for your own classes.
In C++, operator overloading allows redefining standard operators (+, ==, <, <<, etc.)
for user-defined types.
This feature enables class objects to behave like built-in types (such as int or double).
In this article, we will explore arithmetic, comparison, and stream operators step by step using the Book class.
1. What Is Operator Overloading?
Operator overloading allows you to define custom behavior for operators when used with class objects.
For example, two Book objects can be combined using + or compared using ==.
Operator functions are defined like regular member functions:
class ClassName {
public:
ReturnType operator<Operator>(Parameters) {
// custom behavior
}
};
For instance, Book operator+(const Book& other)
means that the + operator can be used between two Book objects.
2. Basic Book Class
The following class represents a book with a title, price, and page count. We’ll use this class to implement various overloaded operators.
#include <iostream>
#include <string>
using namespace std;
class Book {
private:
string title;
double price;
int pages;
public:
Book(string t = "", double p = 0.0, int pg = 0)
: title(t), price(p), pages(pg) {}
void Show() const {
cout << "Book: " << title
<< " | Pages: " << pages
<< " | Price: " << price << " USD" << endl;
}
// Getters
double GetPrice() const { return price; }
int GetPages() const { return pages; }
string GetTitle() const { return title; }
};
3. The + Operator (Combining Two Books)
Let’s say we want to combine two books using the + operator.
The resulting “bundle” book will have a combined price and total page count.
Book operator+(const Book &other) const {
string combinedTitle = title + " & " + other.title;
double combinedPrice = price + other.price;
int combinedPages = pages + other.pages;
return Book(combinedTitle, combinedPrice, combinedPages);
}
Usage:
Book b1("C++ Primer", 180.0, 980);
Book b2("Effective C++", 150.0, 400);
Book combo = b1 + b2;
combo.Show();
Output:
Book: C++ Primer & Effective C++
| Pages: 1380 | Price: 330 USD
4. The == Operator (Equality Comparison)
To check if two books are identical, we can overload the == operator.
For example, if both title and price are the same, we’ll consider them equal.
bool operator==(const Book &other) const {
return (title == other.title &&
pages == other.pages &&
price == other.price);
}
Usage:
Book a("1984", 99.9, 328);
Book b("1984", 99.9, 328);
if (a == b)
cout << "Books are the same." << endl;
else
cout << "Books are different." << endl;
Output:
Books are the same.
5. The < Operator (Comparison)
To compare books based on price, we can overload the < operator.
This is especially useful when sorting (std::sort()) or storing objects in std::set.
bool operator<(const Book &other) const {
return price < other.price;
}
Usage:
Book b1("C++ Primer", 180, 900);
Book b2("Clean Code", 220, 500);
if (b1 < b2)
cout << b1.GetTitle() << " is cheaper." << endl;
Output:
C++ Primer is cheaper.
6. The ++ Operator (Increment Page Count)
The ++ operator can be defined in two forms: prefix and postfix.
In this example, incrementing increases the page count of the book.
// Prefix (++book)
Book& operator++() {
++pages;
return *this;
}
// Postfix (book++)
Book operator++(int) {
Book temp = *this;
pages++;
return temp;
}
Usage:
Book b("C++ 101", 120.0, 250);
++b; // prefix
b++; // postfix
b.Show(); // 252 pages
7. The << Operator (Output with ostream)
To print an object directly using cout << b;,
we must overload the << operator globally.
This operator typically returns a reference to ostream.
friend ostream& operator<<(ostream &os, const Book &b) {
os << "[Book: " << b.title
<< ", Pages: " << b.pages
<< ", Price: " << b.price << " USD]";
return os;
}
Usage:
Book b("Clean Architecture", 175.0, 350);
cout << b << endl;
Output:
[Book: Clean Architecture, Pages: 350, Price: 175 USD]
8. Full Example: All Operators Combined
#include <iostream>
#include <string>
using namespace std;
class Book {
private:
string title;
double price;
int pages;
public:
Book(string t = "", double p = 0, int pg = 0)
: title(t), price(p), pages(pg) {}
// + operator
Book operator+(const Book &other) const {
return Book(title + " & " + other.title,
price + other.price,
pages + other.pages);
}
// == operator
bool operator==(const Book &other) const {
return (title == other.title && price == other.price);
}
// < operator
bool operator<(const Book &other) const {
return price < other.price;
}
// ++ (prefix)
Book& operator++() {
++pages;
return *this;
}
// ++ (postfix)
Book operator++(int) {
Book temp = *this;
pages++;
return temp;
}
// << (ostream)
friend ostream& operator<<(ostream &os, const Book &b) {
os << b.title << " - " << b.price << " USD (" << b.pages << " pages)";
return os;
}
};
int main() {
Book b1("C++ Primer", 180.0, 900);
Book b2("Effective C++", 150.0, 400);
Book combo = b1 + b2; // +
cout << combo << endl; // <<
++combo; // prefix ++
combo++; // postfix ++
cout << "After increment: " << combo << endl;
cout << (b1 < b2 ? "b1 is cheaper" : "b2 is cheaper") << endl;
if (b1 == b2)
cout << "Books are the same." << endl;
else
cout << "Books are different." << endl;
}
Output:
C++ Primer & Effective C++ - 330 USD (1300 pages)
After increment: C++ Primer & Effective C++ - 330 USD (1302 pages)
b1 is cheaper
Books are different.
9. TL;DR
- operator+ → Combines two objects.
- operator== → Checks equality.
- operator< → Used for comparison or sorting.
- operator++ → Increments values (prefix/postfix).
- operator<< → Enables printing with
cout(requires friend). - Operator overloading makes classes behave like built-in types.
- All examples can be compiled and run in Visual Studio 2022 or GCC 11+.