C++: Simple Inheritance

Simple Inheritance

In this video, we gave several example of how inheritance functions in object-oriented programming for simple classes. Here, we give one more example, which is a little more involved than the ones in the video. This example presents a class hierarchy of vehicles with bicycles and trucks as our main objects. With vehicles as our base, we derive the motorized vehicle class and bicycle class from it. We further extend the motorized vehicle class with a truck class. However, the hierarchy is open to extension if we would like to add other vehicles like cars, trains, tanks, etc.

The base class is CVehicle, which is inherited directly by the derived classes CBicycle and CMotorizedVehicle. The member functions MoveForward(), MoveBackward(), and GetLocation(), as well as the member variable miLocation, are all inherited by the derived classes. The entire code is for our program is shown below.

#include <iostream>

// CVehicle is the base class
class CVehicle
{
public:
    CVehicle(int iLoc) : miLocation(iLoc) {}
    ~CVehicle() {}
    void MoveForward() {
        ++miLocation;
    }
    void MoveBackward() {
        --miLocation;
    }
    double GetLocation() {
        return miLocation;
    }
private:
    int miLocation;
};

// CBicycle inherits CVehicle
class CBicycle : public CVehicle
{
public:
    CBicycle(int iLoc = 0) : CVehicle(iLoc) {}
    ~CBicycle() {}
};

// CMotorizedVehicle inherits CVehicle and adds functionality
class CMotorizedVehicle : public CVehicle
{
public:
    CMotorizedVehicle(int iLoc) : CVehicle(iLoc), mbIsOn(true) {}
    ~CMotorizedVehicle() {}
    void TurnOn() {
        mbIsOn = true;
    }
    void TurnOff() {
        mbIsOn = false;
    }
    bool IsOn() {
        return mbIsOn;
    }
private:
    bool mbIsOn;
};

// CTruck inherits CMotorizedVehicle, which in turn, inherits CVehicle
// A truck object can be loaded an unloaded, in adddition to the
// inherited functionality.
class CTruck : public CMotorizedVehicle
{
public:
    CTruck(int iLoc = 0) : CMotorizedVehicle(iLoc), mbHasLoad(false) {}
    ~CTruck() {}
    void Load() {
        mbHasLoad = true;
    }
    void Unload() {
        mbHasLoad = false;
    }
    bool HasLoad() {
        return mbHasLoad;
    }
private:
    bool mbHasLoad;
};

int main() {
    using namespace std;

    // A bike object
    CBicycle qMyBike;
    cout << "The bike is at " << qMyBike.GetLocation() << endl;
    qMyBike.MoveBackward();
    cout << "The bike is at " << qMyBike.GetLocation() << endl;
    qMyBike.MoveForward();
    cout << "The bike is at " << qMyBike.GetLocation() << endl;

    // A truck object
    CTruck qMyTruck(10);
    cout << "The truck is at " << qMyTruck.GetLocation() << endl;
    qMyTruck.MoveBackward();
    cout << "The truck is at " << qMyTruck.GetLocation() << endl;
    qMyTruck.MoveForward();
    cout << "The truck is at " << qMyTruck.GetLocation() << endl;

    cout << "The truck is on = " << qMyTruck.IsOn() << endl;
    qMyTruck.TurnOff();
    cout << "The truck is on = " << qMyTruck.IsOn() << endl;
    qMyTruck.TurnOn();
    cout << "The truck is on = " << qMyTruck.IsOn() << endl;

    cout << "The truck has a load = " << qMyTruck.HasLoad() << endl;
    qMyTruck.Load();
    cout << "The truck has a load = " << qMyTruck.HasLoad() << endl;
    qMyTruck.Unload();
    cout << "The truck has a load = " << qMyTruck.HasLoad() << endl;

    return 0;
}

To clarify the situation, CVehicle is the base class, which is inherited directly by CBicycle and CMotorizedVehicle. The class CMotorizedVehicle inherited by the class CTruck. The full diagram looks something like this:

The class CBicycle inherits functionality from CVehicle, which simply allows for movement along a line. The class CMotorizedVehicle adds functions to turn itself off and on. The class CTruck adds functionality to load and unload itself. So, objects of type CTruck have all of the functionality of CVehicle, CMotorizedVehicle, and CVehicle. In our main function, we demonstrate the functionality of the objects of type CBicylcle and CTruck. Below is the output of the program.

A few other points about this program are in order. Notice that the constructor of CVehicle takes an integer that specifies the starting location of the object when it is instantiated. Hence, when other classes, like CBicycle and CMotorizedVehicle inherit it, they must call the constructor of CVehicle with a location parameter. When we instantiated CBicycle in the main function, we did not pass in a location parameter. This is because the CBicycle constructor is set to have a default parameter of zero if no value is specified. We could have done this as well for the CTruck. However, we wanted to illustrate both instantiations.