In the realm of C++ programming, the input and output operations are seamlessly facilitated by the widely used cin
and cout
streams. These streams, part of the C++ Standard Library, empower users to interact with the console effortlessly. However, a notable hurdle arises when it comes to user-defined class objects. Unlike built-in data types, user-defined classes lack native support for direct integration with the cin
and cout
streams. This intricacy prompts the need for a specialized approach to enable smooth communication between custom classes and these essential I/O streams. Operator overloading is one of the powerful features of C++ that allows us to redefine the behavior of operators for custom classes.
In this Answer, we will explore the concept of operator overloading with a specific focus on overloading the input (<<
) and output (>>
) operators for custom classes.
Operator overloading in C++ enables us to redefine how operators work with user-defined types. This allows us to write code that feels more natural and intuitive when working with objects of our custom classes.
Let’s take a look at how we can overload the <<
and >>
operators for a custom class named Person
.
Enter two strings (space-separated) for the firstName
and the lastName
in the “Enter the input below” section respectively. Then, click the “Run” button to display the output.
#include <iostream>#include <string>using namespace std;class Person {private:string firstName;string lastName;public:Person(string first, string last) : firstName(first), lastName(last) {}// Overload the >> operator to allow cin to read values into Person objectsfriend istream& operator>>(istream& is, Person& obj) {is >> obj.firstName >> obj.lastName;return is;}// Overload the << operator to allow cout to display Person objectsfriend ostream& operator<<(ostream& os, const Person& obj) {os << obj.firstName << " " << obj.lastName;return os;}};int main() {Person obj1("John", "Doe");cout << "Person 1: " << obj1 << endl;Person obj2("", "");cin >> obj2;cout << "Person 2: " << obj2 << endl;return 0;}
Enter the input below
Let's dive into the code given above:
Lines 6–9: We define a class named Person
that has two private member variables, the firstName
and the lastName
, which are strings.
Line 12: We define the constructor for the Person
class that initializes the firstName
and the lastName
member variables with values passed as parameters during object creation.
Lines 15–18: We define a friend function that overloads the >>
operator to allow reading values into the Person
objects. It reads the first and last names from the input stream and assigns them to the firstName
and lastName
members of the Person
object. It then returns the input stream (is
) to allow chaining input operations.
Lines 21–24: We define another friend
function that overloads the <<
operator to allow displaying Person
objects. It outputs the first and last names to the output stream and returns the output stream (os
) to enable chaining output operations.
In the main()
function, we perform the following:
Line 28: Create an object of the Person
class, obj1
, with the firstName
as John
and lastName
as Doe
.
Line 29: Display the information about the obj1
object using the overloaded <<
operator, showing Person 1: John Doe
on the console.
Line 31: Create another object of the Person
class, obj2
, with empty first and last names.
Line 32: Prompt the user to input values for obj2
object, which is read using the overloaded >>
operator.
Line 34: Display the information about obj2
, showing Person 2: <firstName> <lastName>
on the console.
While the innate capabilities of the cin
and cout
streams significantly enhance the user experience in C++ programming, their direct application to user-defined class objects poses a challenge. By implementing operator overloading, we can bridge this gap, enabling seamless integration and empowering users to leverage the full potential of these streams with custom classes.
Free Resources