Loading

C++: Virtual Member Functions

Virtual Member Functions

In this C++ video tutorial, we introduce the notions of polymorphism and overriding functions via virtual member functions. By polymorphism, we mean that a pointer or reference can take on multiple forms of object types.

#include <iostream>

class CIFoodItem
{
public:
    virtual double GetCalories() = 0;
};

class CCarrot : public CIFoodItem
{
public:
    virtual double GetCalories() {
        return 30.0;
    }
};

class CSteak : public CIFoodItem
{
public:
    virtual double GetCalories() {
        return 210.0;
    }
};

class CCake : public CIFoodItem
{
public:
    virtual double GetCalories() {
        return 92.0;
    }
};

int main() {
    using namespace std;

    CIFoodItem* qpaMeal[3];

    CCarrot qCarrot;
    CSteak qSteak;
    CCake qCake;

    qpaMeal[0] = &qCarrot;
    qpaMeal[1] = &qSteak;
    qpaMeal[2] = &qCake;

    double dTotalCal = 0.0;
    for (int iIndex = 0; iIndex < 3; ++iIndex) {
        double dItemCal = qpaMeal[iIndex]->GetCalories();
        cout << "Calories for item#" << iIndex
             << " = " << dItemCal << endl;
        dTotalCal = dTotalCal + dItemCal;
    }
    cout << "Total Calories = " << dTotalCal << endl;

    return 0;
}

The program above contains a base food item class and three derived classes for three food items: carrots, steak, and cake. The base food item class contains a single pure virtual member function to get the calories for a particular food item.

Since this is a pure virtual function and has no body, it is more like a member function pointer than a member function. In fact, classes with pure virtual member functions can not be instantiated and are therefore referred to as abstract. If an abstract class has only pure virtual functions and no data members, like the food item class, we will call it an interface. By our system of Hungarian Notation, we will prefix the interface class names with CI and abstract class names with CA.

We will often refer to classes with no pure virtual functions as concrete because we can instantiate them. The function GetCalories() is overridden in each of our concrete food classes and each returns the calorie count for that particular food item.

The abstract food item class allows us to assemble all of our food items together in one array, which allows us to aggregate our food for a day or, in this case, a meal. In our main function, create one carrot, one steak and one cake and put them together in our meal array. Then we have a for loop, that runs through the food items and calls GetCalories() on each item to get the total calories for our meal. For this example, our food item class is a polymorphic type that provides an interface for our concrete classes. Here, we use it to create a program to monitor a diet.