Arithmetic Operator Overload
Part of the Object Oriented Programming section of Coddy's C++ journey — lesson 41 of 104.
Arithmetic operators like +, -, *, and / are commonly overloaded to make custom classes behave like built-in numeric types. These operators typically return a new object rather than modifying the operands.
Here's a Fraction class with arithmetic operators:
class Fraction {
int numerator, denominator;
public:
Fraction(int n, int d) : numerator(n), denominator(d) {}
Fraction operator+(const Fraction& other) const {
return Fraction(
numerator * other.denominator + other.numerator * denominator,
denominator * other.denominator
);
}
Fraction operator*(const Fraction& other) const {
return Fraction(numerator * other.numerator,
denominator * other.denominator);
}
};Notice that both operators are marked const since they don't modify either operand. They create and return a new Fraction with the result.
For compound assignment operators like +=, the pattern differs. These modify the left operand and return a reference to it:
Fraction& operator+=(const Fraction& other) {
numerator = numerator * other.denominator + other.numerator * denominator;
denominator = denominator * other.denominator;
return *this;
}A common practice is to implement the basic operator in terms of the compound assignment, reducing code duplication:
Fraction operator+(const Fraction& other) const {
Fraction result = *this; // Copy this object
result += other; // Use compound assignment
return result;
}This approach ensures both operators stay consistent and makes maintenance easier.
Challenge
EasyLet's build a Money class that handles currency calculations using arithmetic operator overloading. You'll implement multiple arithmetic operators that let you work with money values as naturally as you would with regular numbers.
You'll create two files to organize your code:
Money.h: Define aMoneyclass that stores an amount in cents (as anint) to avoid floating-point precision issues. Your class should support:- A constructor that takes dollars and cents as separate integers
- A getter
getDollars()that returns the dollar portion - A getter
getCents()that returns the cents portion (0-99) - Overloaded
+and-operators that return a newMoneyobject - Overloaded
+=and-=compound assignment operators that modify the current object and return a reference to it - A
display()method that prints the money in the format$X.YY(always two digits for cents)
Implement the basic operators (
+and-) in terms of the compound assignment operators to reduce code duplication, as shown in the lesson. All arithmetic operators should be markedconstwhere appropriate.main.cpp: Read four integers from input representing two money amounts (dollars1, cents1, dollars2, cents2 on separate lines). Create twoMoneyobjects, then demonstrate all your operators:- Print
"Amount 1: "followed by the first amount displayed - Print
"Amount 2: "followed by the second amount displayed - Add the two amounts and print
"Sum: "followed by the result - Subtract the second from the first and print
"Difference: "followed by the result - Use
+=to add the second amount to the first, then print"After +=: "followed by the modified first amount
- Print
For the display() method, use std::setw(2) and std::setfill('0') from <iomanip> to ensure cents always show two digits (e.g., $5.07 not $5.7).
Convert input strings to integers using std::stoi(). Don't forget header guards in your header file.
Cheat sheet
Arithmetic operators like +, -, *, and / can be overloaded to make custom classes behave like built-in numeric types. These operators typically return a new object rather than modifying the operands.
Basic arithmetic operators should be marked const since they don't modify either operand:
Fraction operator+(const Fraction& other) const {
return Fraction(
numerator * other.denominator + other.numerator * denominator,
denominator * other.denominator
);
}Compound assignment operators like += and -= modify the left operand and return a reference to it:
Fraction& operator+=(const Fraction& other) {
numerator = numerator * other.denominator + other.numerator * denominator;
denominator = denominator * other.denominator;
return *this;
}A common practice is to implement basic operators in terms of compound assignment operators to reduce code duplication:
Fraction operator+(const Fraction& other) const {
Fraction result = *this; // Copy this object
result += other; // Use compound assignment
return result;
}Try it yourself
#include <iostream>
#include <string>
#include "Money.h"
using namespace std;
int main() {
// Read input for two money amounts
string line;
getline(cin, line);
int dollars1 = stoi(line);
getline(cin, line);
int cents1 = stoi(line);
getline(cin, line);
int dollars2 = stoi(line);
getline(cin, line);
int cents2 = stoi(line);
// TODO: Create two Money objects with the input values
// TODO: Print "Amount 1: " followed by first amount displayed
// TODO: Print "Amount 2: " followed by second amount displayed
// TODO: Add the two amounts and print "Sum: " followed by result
// TODO: Subtract second from first and print "Difference: " followed by result
// TODO: Use += to add second amount to first, then print "After +=: " followed by modified first amount
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