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
Shape
class defines a virtual functiondraw
. - The
Circle
andRectangle
classes override thedraw
function. - In the
main
function, base class pointersshape1
andshape2
point toCircle
andRectangle
objects, respectively. - When
draw
is 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
Shape
class is now an abstract class with a pure virtual functiondraw
. - The
Circle
andRectangle
classes override thedraw
function. - The
main
function 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
Animal
class is an abstract base class with a pure virtual functionmakeSound
. - The
Dog
andCat
classes override themakeSound
function. - The
main
function demonstrates polymorphic behavior with base class pointers pointing to derived class objects and calling their respectivemakeSound
functions.
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
Payment
class is an abstract base class with a pure virtual functionprocessPayment
. - The
CreditCardPayment
andPayPalPayment
classes override theprocessPayment
function. - The
main
function demonstrates polymorphic behavior with base class pointers pointing to derived class objects and calling their respectiveprocessPayment
functions.
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.