Introduction
Virtual functions in C++ allow you to achieve runtime polymorphism. They enable a base class to define a function that can be overridden by derived classes. When a base class pointer or reference points to a derived class object, the overridden function in the derived class is called. This allows you to write flexible and reusable code.
Defining and Using Virtual Functions
To declare a virtual function, you use the virtual keyword in the base class. The derived class can override this function to provide its own implementation.
Example: Basic Virtual Function
Let’s create a simple example with a base class Shape and derived classes Circle and Rectangle. Each class will have a draw function to demonstrate virtual functions.
#include <iostream>
using namespace std;
// Base class
class Shape {
public:
// Virtual function
virtual void draw() {
cout << "Drawing Shape" << endl;
}
};
// Derived class
class Circle : public Shape {
public:
// Override the base class function
void draw() override {
cout << "Drawing Circle" << endl;
}
};
// Derived class
class Rectangle : public Shape {
public:
// Override the base class function
void draw() override {
cout << "Drawing Rectangle" << endl;
}
};
int main() {
// Create objects of derived classes
Circle circle;
Rectangle rectangle;
// Create pointers of base class type
Shape* shape1 = &circle;
Shape* shape2 = &rectangle;
// Call the virtual function
shape1->draw(); // Calls Circle's draw
shape2->draw(); // Calls Rectangle's draw
return 0;
}
Output
Drawing Circle
Drawing Rectangle
Explanation
- The
Shapeclass defines a virtual functiondraw. - The
CircleandRectangleclasses override thedrawfunction. - In the
mainfunction, base class pointersshape1andshape2point toCircleandRectangleobjects, respectively. - When
drawis called on these pointers, the overridden function in the derived class is executed.
Pure Virtual Functions and Abstract Classes
A pure virtual function is a virtual function that has no implementation in the base class and must be overridden by derived classes. A class containing at least one pure virtual function is called an abstract class, and it cannot be instantiated.
Example: Pure Virtual Function and Abstract Class
#include <iostream>
using namespace std;
// Abstract base class
class Shape {
public:
// Pure virtual function
virtual void draw() = 0;
};
// Derived class
class Circle : public Shape {
public:
// Override the pure virtual function
void draw() override {
cout << "Drawing Circle" << endl;
}
};
// Derived class
class Rectangle : public Shape {
public:
// Override the pure virtual function
void draw() override {
cout << "Drawing Rectangle" << endl;
}
};
int main() {
// Create objects of derived classes
Circle circle;
Rectangle rectangle;
// Create pointers of base class type
Shape* shape1 = &circle;
Shape* shape2 = &rectangle;
// Call the virtual function
shape1->draw(); // Calls Circle's draw
shape2->draw(); // Calls Rectangle's draw
return 0;
}
Output
Drawing Circle
Drawing Rectangle
Explanation
- The
Shapeclass is now an abstract class with a pure virtual functiondraw. - The
CircleandRectangleclasses override thedrawfunction. - The
mainfunction demonstrates polymorphic behavior with base class pointers pointing to derived class objects.
Practical Examples
Example 1: Animal Sound Hierarchy
Let’s create a base class Animal with a pure virtual function makeSound. Derived classes Dog and Cat will override this function.
#include <iostream>
using namespace std;
// Abstract base class
class Animal {
public:
// Pure virtual function
virtual void makeSound() = 0;
};
// Derived class
class Dog : public Animal {
public:
// Override the pure virtual function
void makeSound() override {
cout << "Woof Woof" << endl;
}
};
// Derived class
class Cat : public Animal {
public:
// Override the pure virtual function
void makeSound() override {
cout << "Meow Meow" << endl;
}
};
int main() {
// Create objects of derived classes
Dog dog;
Cat cat;
// Create pointers of base class type
Animal* animal1 = &dog;
Animal* animal2 = &cat;
// Call the virtual function
animal1->makeSound(); // Calls Dog's makeSound
animal2->makeSound(); // Calls Cat's makeSound
return 0;
}
Output
Woof Woof
Meow Meow
Explanation
- The
Animalclass is an abstract base class with a pure virtual functionmakeSound. - The
DogandCatclasses override themakeSoundfunction. - The
mainfunction demonstrates polymorphic behavior with base class pointers pointing to derived class objects and calling their respectivemakeSoundfunctions.
Example 2: Payment System Hierarchy
Let’s create a base class Payment with a pure virtual function processPayment. Derived classes CreditCardPayment and PayPalPayment will override this function.
#include <iostream>
using namespace std;
// Abstract base class
class Payment {
public:
// Pure virtual function
virtual void processPayment(double amount) = 0;
};
// Derived class
class CreditCardPayment : public Payment {
public:
// Override the pure virtual function
void processPayment(double amount) override {
cout << "Processing credit card payment of $" << amount << endl;
}
};
// Derived class
class PayPalPayment : public Payment {
public:
// Override the pure virtual function
void processPayment(double amount) override {
cout << "Processing PayPal payment of $" << amount << endl;
}
};
int main() {
// Create objects of derived classes
CreditCardPayment ccPayment;
PayPalPayment ppPayment;
// Create pointers of base class type
Payment* payment1 = &ccPayment;
Payment* payment2 = &ppPayment;
// Call the virtual function
payment1->processPayment(100.0); // Calls CreditCardPayment's processPayment
payment2->processPayment(200.0); // Calls PayPalPayment's processPayment
return 0;
}
Output
Processing credit card payment of $100
Processing PayPal payment of $200
Explanation
- The
Paymentclass is an abstract base class with a pure virtual functionprocessPayment. - The
CreditCardPaymentandPayPalPaymentclasses override theprocessPaymentfunction. - The
mainfunction demonstrates polymorphic behavior with base class pointers pointing to derived class objects and calling their respectiveprocessPaymentfunctions.
Conclusion
Virtual functions in C++ enable runtime polymorphism, allowing derived classes to override base class functions and enabling flexible and reusable code. This chapter covered the basics of defining virtual functions, pure virtual functions, and abstract classes, with practical examples demonstrating their usage. Understanding and effectively using virtual functions is essential for writing robust and maintainable C++ programs.