Stream Operators
Part of the Object Oriented Programming section of Coddy's C++ journey — lesson 43 of 104.
The stream insertion (<<) and extraction (>>) operators let you use your custom classes with std::cout and std::cin. Unlike the operators we've covered so far, these must be implemented as non-member functions because the left operand is a stream, not your class.
class Point {
int x, y;
public:
Point(int x, int y) : x(x), y(y) {}
// Declare as friend to access private members
friend std::ostream& operator<<(std::ostream& os, const Point& p);
friend std::istream& operator>>(std::istream& is, Point& p);
};
std::ostream& operator<<(std::ostream& os, const Point& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
std::istream& operator>>(std::istream& is, Point& p) {
is >> p.x >> p.y;
return is;
}Both operators return a reference to the stream, enabling chaining like std::cout << p1 << p2. The insertion operator takes the object by const reference since it only reads data, while extraction takes a non-const reference because it modifies the object.
Now you can use Point naturally with streams:
Point p(3, 4);
std::cout << "Location: " << p << std::endl; // Output: Location: (3, 4)
Point p2(0, 0);
std::cin >> p2; // Read two integers into p2Challenge
EasyLet's build a Temperature class that can be seamlessly used with std::cout and std::cin through stream operator overloading. This is a practical scenario where you want to display temperatures in a readable format and read them from input naturally.
You'll create two files to organize your code:
Temperature.h: Define aTemperatureclass that stores a value in Celsius (as adouble) and a unit label (as achar, either'C'for Celsius or'F'for Fahrenheit). Your class should have:- Private members for the temperature value and unit
- A default constructor that initializes to 0.0 Celsius
- A parameterized constructor that takes a value and unit
- Getters
getValue()andgetUnit()(both const) - Friend declarations for the stream insertion (
<<) and extraction (>>) operators
Implement the stream operators as non-member functions:
- The insertion operator should output the temperature in the format
VALUE UNIT(e.g.,25.5 Cor77.9 F). Use one decimal place for the value. - The extraction operator should read a value and a unit character from the stream and store them in the Temperature object.
Both operators must return a reference to the stream to enable chaining.
main.cpp: Read two temperatures from input. Each temperature is provided on a separate line in the formatvalue unit(e.g.,25.5 C).Create two
Temperatureobjects using the extraction operator to read them fromstd::cin. Then output them using the insertion operator in this format:Temperature 1: <temp1> Temperature 2: <temp2>For example, if the input is:
25.5 C 98.6 FThe output should be:
Temperature 1: 25.5 C Temperature 2: 98.6 F
Use std::fixed and std::setprecision(1) from <iomanip> to format the temperature value with exactly one decimal place. Don't forget header guards in your header file.
Cheat sheet
Stream insertion (<<) and extraction (>>) operators allow custom classes to work with std::cout and std::cin. These operators must be implemented as non-member functions because the left operand is a stream object, not your class.
Basic Syntax
class Point {
int x, y;
public:
Point(int x, int y) : x(x), y(y) {}
// Declare as friend to access private members
friend std::ostream& operator<<(std::ostream& os, const Point& p);
friend std::istream& operator>>(std::istream& is, Point& p);
};
std::ostream& operator<<(std::ostream& os, const Point& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
std::istream& operator>>(std::istream& is, Point& p) {
is >> p.x >> p.y;
return is;
}Key Points
- Both operators return a reference to the stream to enable chaining (e.g.,
std::cout << p1 << p2) - The insertion operator (
<<) takes the object byconstreference since it only reads data - The extraction operator (
>>) takes a non-const reference because it modifies the object - Use
frienddeclarations to allow these non-member functions to access private members
Usage Example
Point p(3, 4);
std::cout << "Location: " << p << std::endl; // Output: Location: (3, 4)
Point p2(0, 0);
std::cin >> p2; // Read two integers into p2Try it yourself
#include <iostream>
#include "Temperature.h"
int main() {
// TODO: Create two Temperature objects
// TODO: Use the extraction operator (>>) to read two temperatures from std::cin
// TODO: Output the temperatures using the insertion operator (<<)
// Format:
// Temperature 1: <temp1>
// Temperature 2: <temp2>
return 0;
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesC++ Build & CompilationHeader Files & Source FilesNamespaces & ScopeIntroduction to OOP in C++Classes vs ObjectsThe 'this' PointerMethods (Member Functions)Attributes (Data Members)Ctors & Dtors BasicsRecap - Simple Calculator4Class Properties
Instance vs Static MembersGetters and SettersConst Member FunctionsMutable KeywordStatic Methods and VariablesFriend Functions & ClassesRecap - Bank Account Manager7Inheritance
Basic InheritanceInheritance Access LevelsCtor & Dtor Call OrderMethod OverridingVirtual Functions & VTableMultiple InheritanceVirtual InheritanceRecap - Employee Hierarchy2Memory Management
Stack vs Heap MemoryPointers and ReferencesDynamic Memory (new/delete)Smart Pointers in C++RAII in C++Recap - Dynamic Array Manager5Encapsulation
Access Specifiers in C++Access Specifiers In DepthInformation HidingStruct vs ClassNested & Inner ClassesRecap - Student Records System8Polymorphism
Compile vs Runtime PolymorphFunction OverloadingVirtual Functions RevisitedPure Virtual FunctionsAbstract ClassesInterface Design in C++Dynamic Casting & RTTIRecap - Shape Calculator3Constructors & Destructors
Default ConstructorParameterized ConstructorCopy ConstructorMove ConstructorConstructor Init ListsDelegating ConstructorsDestructor Deep DiveRule of Three / Five / ZeroRecap - String Class6Operator Overloading
Intro to Operator OverloadArithmetic Operator OverloadComparison Operator OverloadStream OperatorsAssignment Operator Overload[] and () Operator OverloadType Conversion OperatorsRecap - Matrix Class9Templates
Function TemplatesClass TemplatesTemplate SpecializationVariadic TemplatesSFINAE & Type Traits BasicsRecap - Generic Container