Overloading Insertion (<<) and Extraction (>>) Operators in C++
In C++, the insertion (<<) and extraction (>>) operators are commonly used for input and output operations. These operators can be overloaded to work seamlessly with user-defined types, enabling custom objects to be displayed and read using standard I/O streams.
Why Overload Insertion and Extraction Operators?
By overloading these operators, you can:
- Display objects in a readable format using
std::cout. - Input data into objects directly using
std::cin. - Make your custom types integrate well with C++ I/O streams.
Overloading the Insertion Operator (<<)
The insertion operator (<<) is overloaded to define how objects of a class are output to an output stream like std::cout. Below is an example:
#include <iostream>
class Complex {
private:
double real, imag;
public:
Complex(double real = 0, double imag = 0) : real(real), imag(imag) {}
// Friend function to overload <<
friend std::ostream& operator<<(std::ostream& out, const Complex& c);
};
// Overloading the << operator
std::ostream& operator<<(std::ostream& out, const Complex& c) {
out << c.real << " + " << c.imag << "i";
return out;
}
int main() {
Complex c1(3, 4), c2(1.5, 2.5);
std::cout << "Complex number 1: " << c1 << std::endl;
std::cout << "Complex number 2: " << c2 << std::endl;
return 0;
}
Output:
Complex number 1: 3 + 4i
Complex number 2: 1.5 + 2.5i
Here, the friend function operator<< defines how the Complex object is formatted when output to the stream.
Overloading the Extraction Operator (>>)
The extraction operator (>>) is overloaded to define how objects of a class are input from an input stream like std::cin. Below is an example:
#include <iostream>
class Complex {
private:
double real, imag;
public:
Complex(double real = 0, double imag = 0) : real(real), imag(imag) {}
// Friend function to overload >>
friend std::istream& operator>>(std::istream& in, Complex& c);
};
// Overloading the >> operator
std::istream& operator>>(std::istream& in, Complex& c) {
std::cout << "Enter real part: ";
in >> c.real;
std::cout << "Enter imaginary part: ";
in >> c.imag;
return in;
}
int main() {
Complex c1;
std::cout << "Input a complex number:\n";
std::cin >> c1;
std::cout << "You entered: " << c1 << std::endl;
return 0;
}
Output (Example Interaction):
Input a complex number:
Enter real part: 5
Enter imaginary part: 6
You entered: 5 + 6i
The friend function operator>> allows the Complex object to read values for its members directly from the input stream.
Combining Insertion and Extraction Operators
You can use both operators together to enable seamless I/O for your custom types. Here is an example:
#include <iostream>
class Point {
private:
int x, y;
public:
Point(int x = 0, int y = 0) : x(x), y(y) {}
// Friend function to overload <<
friend std::ostream& operator<<(std::ostream& out, const Point& p);
// Friend function to overload >>
friend std::istream& operator>>(std::istream& in, Point& p);
};
// Overloading the << operator
std::ostream& operator<<(std::ostream& out, const Point& p) {
out << "(" << p.x << ", " << p.y << ")";
return out;
}
// Overloading the >> operator
std::istream& operator>>(std::istream& in, Point& p) {
std::cout << "Enter x-coordinate: ";
in >> p.x;
std::cout << "Enter y-coordinate: ";
in >> p.y;
return in;
}
int main() {
Point p;
std::cout << "Input a point:\n";
std::cin >> p;
std::cout << "You entered: " << p << std::endl;
return 0;
}
Output (Example Interaction):
Input a point:
Enter x-coordinate: 10
Enter y-coordinate: 20
You entered: (10, 20)
Conclusion
Overloading the insertion (<<) and extraction (>>) operators in C++ enhances the usability of custom types by integrating them seamlessly with standard I/O streams. These overloaded operators provide a natural way to display and input objects, improving code readability and maintainability.