Object Oriented ProgrammingUnit 118 min read
Static Members & Function Overloading: Key OOP Concepts
Unit 11 of Object Oriented Programming: Explores static members (variables/functions shared across all class objects) and function overloading (multiple functions with same name but different parameters), with practical examples, comparisons, and real-world applications in Nepal’s tech ecosystem.
TAKEAWAYS:
- Static members belong to the class, not individual objects, and are initialized once at program start.
- Function overloading allows multiple functions with the same name but different parameters (type/number).
- Static members reduce memory usage by sharing data across all objects of a class.
- Overloaded functions improve code readability by using intuitive function names.
- Static functions cannot access non-static members directly.
- Overloading is resolved at compile-time, while overriding is runtime polymorphism.
Static Members in C++
1. Static Member Variables
Static member variables are shared among all objects of a class. They are declared with the static keyword and belong to the class itself, not to any specific object.
Key Characteristics
- Single copy: Only one instance exists for all objects.
- Class scope: Accessed via the class name (e.g.,
ClassName::staticVar). - Initialization: Must be done outside the class (in a
.cppfile or global scope). - Memory efficiency: Saves memory by avoiding duplicate copies for each object.
Example: Counter for Objects
class Counter {
public:
static int count; // Static member declaration
Counter() { count++; } // Increment on each object creation
};
int Counter::count = 0; // Initialization (outside class)
State After Object Creation:
When to Use Static Members
- Track the number of objects created (e.g.,
Employee::totalEmployees). - Store configuration settings shared by all objects (e.g.,
Database::maxConnections). - Implement singleton patterns (only one instance allowed).
2. Static Member Functions
Static member functions can be called without creating an object. They can only access static members (not instance-specific data).
Example: Utility Function
class MathUtils {
public:
static int add(int a, int b) { return a + b; } // Static function
};
Call Without Object:
int result = MathUtils::add(5, 3); // Output: 8
Comparison: Static vs. Non-Static Members
| Feature | Static Member | Non-Static Member |
|---|---|---|
| Scope | Class-level | Object-level |
| Memory Allocation | One copy for all objects | One copy per object |
| Access | Via class name | Via object reference |
| Initialization | Outside class | Inside constructor |
| Can Access | Only static members | All members |
3. Real-World Example: eSewa Transaction Log
Product: eSewa (Nepal’s digital payment app) Idea Used: Static member to track total transactions globally.
class TransactionLog {
private:
static int totalTransactions; // Shared across all users
public:
void recordTransaction() { totalTransactions++; }
};
int TransactionLog::totalTransactions = 0;
Why?
- eSewa needs a single counter for all users to display "Total Transactions: 1,000,000+".
- Static variable ensures consistency without per-user memory overhead.
Function Overloading in C++
1. Definition
Function overloading allows multiple functions with the same name but different parameters (number, type, or order). Resolved at compile-time.
Syntax
returnType functionName(parameterList1) { ... }
returnType functionName(parameterList2) { ... }
Example: Overloaded area() Function
class Shape {
public:
double area(double side) { return side * side; } // Square
double area(double length, double breadth) { return length * breadth; } // Rectangle
};
Call:
Shape s;
double squareArea = s.area(5); // Calls first function
double rectArea = s.area(4, 6); // Calls second function
2. How Overloading Works
- Compile-time resolution: The compiler selects the correct function based on arguments.
- Same return type: Return types alone cannot differentiate overloaded functions (must differ by parameters).
- Different signatures: Parameter count/type/order must vary.
Example: Overloaded print() for Different Data Types
void print(int x) { cout << "Integer: " << x << endl; }
void print(double x) { cout << "Double: " << x << endl; }
void print(string s) { cout << "String: " << s << endl; }
Trace:
flowchart TD
A["print(5)"] --> B["Calls print(int)"]
C["print(3.14)"] --> D["Calls print(double)"]
E["print('Hello')"] --> F["Calls print(string)"]3. Overloading vs. Overriding
| Feature | Function Overloading | Function Overriding |
|---|---|---|
| Scope | Same class | Derived class |
| Resolution | Compile-time | Runtime (polymorphism) |
| Parameters | Must differ | Same signature |
| Return Type | Can differ | Must match or covariant |
| Inheritance | Not related to inheritance | Requires inheritance |
Example: Overriding in Inheritance
class Animal {
public:
virtual void sound() { cout << "Animal sound" << endl; }
};
class Dog : public Animal {
public:
void sound() override { cout << "Bark!" << endl; } // Overrides
};
4. Real-World Example: Daraz Order Processing
Product: Daraz (Nepal’s e-commerce platform)
Idea Used: Overloaded processOrder() for different order types.
class Order {
public:
void processOrder(int orderId) { /* Standard order */ }
void processOrder(int orderId, string deliveryAddress) { /* Express order */ }
};
Why?
- Daraz handles different order types (standard, express, return) with the same function name but varied parameters.
- Improves code readability and reduces redundancy.
Exam Tip: Key Focus Areas
Static Members:
- Know how to declare/initialize static variables and functions.
- Understand their scope and memory behavior.
- Practice tracking shared data (e.g., object count, global settings).
Function Overloading:
- Differentiate from overriding (compile-time vs. runtime).
- Write overloaded functions for different data types/parameters.
- Avoid ambiguity (e.g., same parameters but different return types).
Common Pitfalls:
- Forgetting to initialize static members outside the class.
- Overloading functions with only return type differences.
- Calling non-static members in static functions.
Problem-Solving:
- Static: Use when data is shared across all objects (e.g., counters, constants).
- Overloading: Use for functions with similar logic but different inputs (e.g.,
area()for shapes).
Worked Example: Bank Loan Interest Calculation
class Loan {
private:
static double baseRate; // Shared interest rate
double principal;
public:
Loan(double p) : principal(p) {}
double calculateInterest(int years) { return principal * baseRate * years / 100; }
};
double Loan::baseRate = 5.5; // Global rate for all loans
// Usage:
Loan homeLoan(1000000);
cout << homeLoan.calculateInterest(5); // Output: 275,000 (5.5% for 5 years)
Why Static?
- The base interest rate (
5.5%) is the same for all loans, so it’s stored statically. - If changed once (e.g., to
6%), all loans reflect the update automatically.
Mermaid Flowchart: Static Member Initialization
flowchart TD
A["Class Definition"] --> B["Declare static member (e.g., `static int baseRate = 5.5;`)"]
B --> C["Initialize outside class (e.g., `int Loan::baseRate = 5.5;`)"]
C --> D["Access via ClassName::member (e.g., `Loan::baseRate`)"]
D --> E["Shared across all Loan objects"]
E --> F["Update once (e.g., `Loan::baseRate = 6.0;`)"]
F --> G["All objects reflect change automatically"]Based on the TU BIT syllabus for Object Oriented Programming (BIT153), unit 11.
Discussion
Loading…