๐Ÿ”ง
Chapter 5

Functions

Master user-defined functions, parameter passing methods, and virtual functions in C++.

5.1 User-Defined Functions

Functions are reusable blocks of code that perform specific tasks.

Aspect Definition Example
Function Definition Block of code that performs a specific task. void display() { cout << "Hello!"; }
Function Declaration Declares a function's name and signature. void display();
Function Call Invokes the function to execute. display();
Return Type Specifies the type of value the function returns. int sum(int a, int b) { return a + b; }
Advantages Reusability, modularity, easier debugging. Reuse logic with different inputs
โ–ถ User-Defined Functions Example
#include <iostream>
using namespace std;

// Function declaration
void greet();
int add(int a, int b);
void displayTesla(int model);

// Function definitions
void greet() {
    cout << "Welcome to 369 Tesla!" << endl;
}

int add(int a, int b) {
    return a + b;
}

void displayTesla(int model) {
    cout << "Tesla Model: " << model << endl;
}

int main() {
    greet();
    
    int result = add(369, 100);
    cout << "Sum: " << result << endl;
    
    displayTesla(3);
    
    return 0;
}
Click "Run Code" to execute

5.2 Parameter Passing Methods

Different ways to pass arguments to functions in C++.

Aspect Definition Example
Call by Value Passes a copy of the argument. void increment(int x) { x++; }
Call by Reference Passes the reference of the argument. void increment(int &x) { x++; }
Call by Pointer Passes the memory address of the argument. void increment(int *x) { (*x)++; }

๐ŸŽฏ Interactive Parameter Passing Demonstration

See how different parameter passing methods affect variables:

โ–ถ Parameter Passing Comparison
#include <iostream>
using namespace std;

// Call by Value - Copy is passed
void incrementByValue(int x) {
    x = x + 10;
    cout << "Inside incrementByValue: " << x << endl;
}

// Call by Reference - Original variable is modified
void incrementByReference(int &x) {
    x = x + 10;
    cout << "Inside incrementByReference: " << x << endl;
}

// Call by Pointer - Address is passed
void incrementByPointer(int *x) {
    *x = *x + 10;
    cout << "Inside incrementByPointer: " << *x << endl;
}

int main() {
    int num1 = 369;
    int num2 = 369;
    int num3 = 369;
    
    cout << "Original values: " << num1 << ", " << num2 << ", " << num3 << endl;
    cout << endl;
    
    // Call by Value
    incrementByValue(num1);
    cout << "After incrementByValue: " << num1 << endl;
    cout << endl;
    
    // Call by Reference
    incrementByReference(num2);
    cout << "After incrementByReference: " << num2 << endl;
    cout << endl;
    
    // Call by Pointer
    incrementByPointer(&num3);
    cout << "After incrementByPointer: " << num3 << endl;
    
    return 0;
}
Click "Run Code" to execute

5.3 Virtual Functions

Virtual functions enable runtime polymorphism in C++.

Aspect Definition Example
Virtual Function Function in base class that can be overridden. virtual void display();
Overriding Redefining a base class method in derived class. void display() override;
Use Case Enables run-time polymorphism. Dynamically decides which function to call
V-Table Mechanism to implement virtual functions. Stores function pointers
โ–ถ Virtual Functions and Polymorphism
#include <iostream>
using namespace std;

class Vehicle {
public:
    virtual void display() {
        cout << "This is a Vehicle" << endl;
    }
    
    virtual void start() {
        cout << "Vehicle starting..." << endl;
    }
};

class Tesla : public Vehicle {
public:
    void display() override {
        cout << "This is a Tesla Electric Vehicle" << endl;
    }
    
    void start() override {
        cout << "Tesla silently starting... โšก" << endl;
    }
    
    void autopilot() {
        cout << "Autopilot engaged! ๐Ÿš—" << endl;
    }
};

class ModelS : public Tesla {
public:
    void display() override {
        cout << "This is a Tesla Model S" << endl;
    }
};

int main() {
    // Polymorphism in action
    Vehicle* vehicle1 = new Tesla();
    Vehicle* vehicle2 = new ModelS();
    
    vehicle1->display();  // Calls Tesla::display()
    vehicle1->start();    // Calls Tesla::start()
    
    cout << endl;
    
    vehicle2->display();  // Calls ModelS::display()
    vehicle2->start();    // Calls Tesla::start()
    
    delete vehicle1;
    delete vehicle2;
    
    return 0;
}
Click "Run Code" to execute

๐Ÿ“Š Virtual Function Table (V-Table) Visualization

๐ŸŒณ Inheritance Hierarchy

๐Ÿ“š Call Stack Visualization

Understanding how function calls are managed in memory:

โ–ถ Recursion Example
#include <iostream>
using namespace std;

int factorial(int n) {
    cout << "Calculating factorial(" << n << ")" << endl;
    
    if (n <= 1) {
        return 1;
    }
    
    return n * factorial(n - 1);
}

int main() {
    int result = factorial(5);
    cout << "Result: " << result << endl;
    return 0;
}
Click "Run Code" to execute

๐Ÿ’ก Practice Exercise

Try modifying the code examples above to:

  • Create your own function that calculates the area of a circle
  • Experiment with different parameter passing methods
  • Create a class hierarchy with virtual functions
  • Write a recursive function to calculate Fibonacci numbers