OOP

Virtual functions

In object-oriented programming (OOP), specifically C++, virtual functions are a mechanism that allows derived classes to redefine functions inherited from their base class. This concept is crucial for achieving polymorphism, a core principle of OOP.

Here’s a breakdown of virtual functions:

What they are:

Key points:

Benefits:

Why virtual is Important in the Base Class:

Without virtual, if you call deposit on a base class pointer pointing to a derived class object, the base class’s deposit function would always be called, regardless of the object’s type. This defeats the purpose of overriding and achieving specialized behavior in derived classes.

Example: Issues Without virtual

link to the source file

class BankAccount
{
public:
    void deposit(double amount)
    {
        // Base class implementation (common logic for all accounts)
        balance += amount;
        cout << "\ninside base class deposit" << endl;
    }

protected:
    double balance = 0.0;
};

class SavingAccount : public BankAccount
{
public:
    void deposit(double amount)
    {
        // Derived class implementation (specific to savings accounts)
        balance += amount + (amount * interestRate);
        cout << "\ninside derived SavingAccount class deposit" << endl;
    }
private:
    double interestRate = 0.01; // Example interest rate
};

class CheckingAccount : public BankAccount
{
public:
    void deposit(double amount)
    {
        // Derived class implementation (deduct fee)
        balance += amount - fee;
        cout << "\ninside derived CheckingAccount class deposit" << endl;
    }
private:
    double fee = 2.0; // Example fee
};

int main()
{
    BankAccount *genericPtr;    // Base class pointer
    SavingAccount mySavings;    // Create a SavingAccount object
    CheckingAccount myChecking; // Create a CheckingAccount object

    genericPtr = &mySavings;    // Points to SavingAccount
    genericPtr->deposit(100.0); // Calls BankAccount's deposit (incorrect)

    genericPtr = &myChecking;   // Points to CheckingAccount
    genericPtr->deposit(100.0); // Calls BankAccount's deposit (incorrect)
}

In this case, calling deposit through the base class pointer (genericPtr) would always execute the BankAccount’s deposit function, even for derived class objects. This would lead to incorrect behavior:

Best Practices:

In Conclusion:

While removing virtual might not cause issues in a limited example, it’s strongly recommended to keep it in the base class for these reasons: