CSC166 Object Oriented Programming

Object Oriented ProgrammingUnit 49 min read

Operator Overloading: Syntax, Rules, and Real-World Applications

Unit 4 of Object Oriented Programming explores operator overloading in C++, including syntax, rules, and practical examples. Learn how to overload operators like +, -, ==, and << for custom classes, understand restrictions, and see how it simplifies code for real-world problems like financial conversions, geometric cal

Key Concepts and Definitions

1. What is Operator Overloading?

Operator overloading allows existing operators (like +, -, <<, >>) to be redefined for user-defined data types (classes/structs). This makes code more intuitive and readable.

Example: Overloading + for a Complex class to add two complex numbers:

class Complex {
    int real, imag;
public:
    Complex(int r = 0, int i = 0) : real(r), imag(i) {}
    Complex operator + (Complex const &obj) {
        Complex res;
        res.real = real + obj.real;
        res.imag = imag + obj.imag;
        return res;
    }
};

Visualization: How + works for Complex objects:

A + B → (A.real + B.real) + i(A.imag + B.imag)

2. How Operator Overloading Works

Syntax Rules

  • Must be a member function or a friend function.
  • Cannot change precedence or associativity of operators.
  • Cannot introduce new operators (only existing ones like +, ==, <<).
  • Cannot overload:
    • :: (scope resolution)
    • .* (member pointer)
    • ?: (ternary conditional)
    • sizeof

Types of Operator Overloading

Category Example Operators Use Case
Arithmetic +, -, *, /, % Math operations (e.g., Complex addition)
Relational ==, !=, <, > Comparisons (e.g., Point distance)
Bitwise &, ` , ^, ~`, <<, >>
Assignment =, +=, -=, *=, /= Compound assignments
Increment/Decrement ++, -- (prefix/postfix) Iterators, counters
Stream <<, >> (for cout/cin) Custom I/O (e.g., Rupee ↔ Dollar)
Subscript [] Custom containers (e.g., Matrix access)

3. Worked Example: Overloading + for a Point Class

Problem: Calculate Euclidean distance between two Point objects. Solution:

#include <iostream>
#include <cmath>
using namespace std;

```figure
{"type":"graph","fns":[{"expr":"sqrt((x2-x1)^2 + (y2-y1)^2)","label":"Distance between P1 (3,4) and P2 (6,8)"}],"x":[2,7],"y":[3,9],"points":[{"x":3,"y":4,"label":"P1 (3,4)","color":"red"},{"x":6,"y":8,"label":"P2 (6,8)","color":"blue"}],"lines":[{"from":{"x":3,"y":4},"to":{"x":6,"y":8},"label":"Distance vector","arrow":true}],"caption":"Euclidean distance between Point P1 (3,4) and P2 (6,8) = 5 units"}

class Point { int x, y; public: Point(int a = 0, int b = 0) : x(a), y(b) {} double distance(Point p) { return sqrt(pow(x - p.x, 2) + pow(y - p.p, 2)); } // Overload << for output friend ostream& operator << (ostream &out, Point p) { out << "(" << p.x << ", " << p.y << ")"; return out; } };

int main() { Point p1(3, 4), p2(6, 8); cout << "Distance: " << p1.distance(p2) << endl; return 0; }

**Output:**

Distance: 5


**Visualization: Euclidean Distance Calculation**

4. Overloading Stream Operators (<< and >>)

Example: Convert Rupee ↔ Dollar (1 USD = 133 NPR).

class Rupee {
    int amount;
public:
    Rupee(int a = 0) : amount(a) {}
    // Conversion operator to Dollar
    operator Dollar() {
        return Dollar(amount / 133);
    }
    // Overload << for output
    friend ostream& operator << (ostream &out, Rupee r) {
        out << r.amount << " NPR";
        return out;
    }
};

class Dollar {
    int amount;
public:
    Dollar(int a = 0) : amount(a) {}
    // Overload >> for input
    friend istream& operator >> (istream &in, Dollar &d) {
        cout << "Enter amount in USD: ";
        in >> d.amount;
        return in;
    }
    // Overload << for output
    friend ostream& operator << (ostream &out, Dollar d) {
        out << d.amount << " USD";
        return out;
    }
};

Trace:

Step Action Output/Input
1 Rupee r(1330); r = 1330 NPR
2 Dollar d = r; (implicit call) d = 10 USD
3 cin >> d; User enters 5 → d = 5 USD

5. Overloading == for a Book Class (Exam-Style Problem)

Problem: A bookshop tracks books with title, author, price, and stock. Overload == to compare two Book objects. Solution:

class Book {
    string title, author;
    int price, stock;
public:
    Book(string t, string a, int p, int s)
        : title(t), author(a), price(p), stock(s) {}
    bool operator == (Book &b) {
        return (title == b.title && author == b.author);
    }
};

```mermaid
classDiagram
    class Book {
        -title: string
        -author: string
        -price: int
        -stock: int
        +operator==(Book b): bool
    }
    Book --> Book : "Compares title and author"
    note for Book "Returns true if both title and author match\nExample: Book1 == Book2 if Book1.title == Book2.title AND Book1.author == Book2.author"

int main() { Book b1("C++", "Bjarne Stroustrup", 500, 10); Book b2("C++", "Bjarne Stroustrup", 600, 5); if (b1 == b2) cout << "Same book!"; else cout << "Different books."; return 0; }

**Output:**

Same book!

Visualization: Book Comparison Logic


6. Overloading [] for a Custom Array Class

Example: A Matrix class where matrix[i][j] accesses elements.

class Matrix {
    int **data;
    int rows, cols;
public:
    Matrix(int r, int c) : rows(r), cols(c) {
        data = new int*[rows];
        for (int i = 0; i < rows; i++)
            data[i] = new int[cols];
    }
    int& operator [] (int i) {
        return *data[i];
    }
};

```figure
{"type":"array","values":["A","B","C","D","E"],"highlight":[2],"caption":"Accessing element at index 2 using overloaded `[]` operator (returns 'C')"}

int main() { Matrix m(2, 2); m[0][1] = 5; // Accesses row 0, column 1 return 0; }

**Visualization: 2D Array Access**

7. Operator Overloading vs. Function Overloading

Feature Operator Overloading Function Overloading
Purpose Redefine operators for custom types Same function name, different parameters
Syntax Uses operator+ or operator<< func(int x) vs. func(double x)
Use Case Math operations, I/O, comparisons Polymorphism, generic functions
Example Complex a + b; print(int x) vs. print(string s)

8. Common Mistakes and Pitfalls

  1. Overloading = incorrectly: Always return a reference to avoid infinite recursion.
    // Wrong: returns by value (infinite loop)
    Complex operator = (Complex c) { ... }
    // Correct: returns reference
    Complex& operator = (Complex &c) { ... }
    
  2. Forgetting friend for stream operators: << and >> must be friends to access private members.
  3. Changing operator precedence: Overloading + for Complex won’t make it right-associative like +=.

In the Real World

  1. Khalti/Daraz Payment Systems

    • Idea Used: Operator overloading for currency conversion (e.g., Rupee ↔ Dollar).
    • How: When a user pays in NPR but the merchant’s system expects USD, the backend uses overloaded + or * to convert amounts seamlessly.
    • Example: If a Daraz order costs $10, the system converts it to 1330 NPR using a conversion operator.
  2. Ncell Billing System

    • Idea Used: Overloading + for call duration calculations.
    • How: If a user makes two calls of 10 and 20 minutes, the system uses CallDuration + CallDuration to compute total talk time.
    • Example:
      class CallDuration {
          int minutes;
      public:
          CallDuration operator + (CallDuration c) {
              return CallDuration(minutes + c.minutes);
          }
      };
      
  3. eSewa Utility Bill Payments

    • Idea Used: Overloading << for structured bill output.
    • How: When you pay an electricity bill, eSewa displays the breakdown (e.g., Unit Consumed: 100, Total Cost: 1500 NPR) using overloaded stream operators for clean formatting.

Exam Tip

  1. Always show the prototype: For operator +, write:
    Complex operator + (Complex const &obj);
    
  2. Handle edge cases: If overloading ==, consider nullptr checks or empty objects.
  3. Use friend for stream operators: Never forget friend ostream& operator << (ostream &out, Class obj).
  4. Practice with Point, Complex, and Rupee classes: These are highly examinable.
  5. Avoid overloading &&, ||, and ,: These are restricted and rarely tested.
  6. Trace step-by-step: For questions like "convert Rupee to Dollar," show the conversion logic in a table.

Final Note: Operator overloading makes C++ code elegant and intuitive. Master it by practicing with geometric shapes (Point, Line), financial conversions (Rupee, Dollar), and custom containers (Matrix, String). Always visualize how operators work under the hood!

In the real world

  • eSewa: Uses operator overloading for custom data types in transaction processing (e.g., overloading + for Transaction objects to combine amounts).
  • Nepali Banks (e.g., NMB, Global IME): Overload << and >> for Account objects to format transaction logs and parse user inputs in mobile banking apps.
  • Pathao/Daraz: Overload == for Order objects to check if two orders are identical (e.g., same items, same delivery address) during fraud detection.

Based on the TU BSc CSIT syllabus for Object Oriented Programming (CSC166), unit 4.

Discussion

Loading…