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:
virtual
keyword within a base class.virtual
is Important in the Base Class:virtual
is to enable polymorphism, a core tenet of object-oriented programming. Polymorphism allows you to treat objects of different derived classes (like SavingAccount
) uniformly through a base class pointer or reference. When you call a virtual function through a base class pointer, the correct overridden version from the actual object type (derived class) is executed at runtime.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.
virtual
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:
SavingAccount
wouldn’t receive the interest.CheckingAccount
wouldn’t deduct the fee.virtual
, it might lead to problems as your codebase grows and incorporates more derived classes.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: