Often a situation arises where one class is a natural extension of another. Taking part of the RPG tutorial as an example, in a fantasy game the players would be able to collect Items, but also Weapons and Armour. All would share properties in common such as weight and monetary value, but the Weapons would also know about damage and the Armour about defense. Of course we could just write three separate classes for each of these and add the same properties to each of them, but a more efficient approach is to use inheritance.

The Item class would be the base or parent class and would contain all the properties that the three classes share. The Weapon and Armour classes would then inherit those properties from the parent Item class; they are the derived or child classes. When one class inherits from another, it takes on all the member variables and functions of its parent (constrained by their access specifiers).

// Define the base class
class Item
{
    public:

    float weight;
    float value;

    Item(float pWeight, float pValue)
    {
        weight = pWeight;
        value = pValue;
    }
};

// Weapon class inherits publicly from the Item class
class Weapon : public Item
{
    public:

    // All declarations from the parent class are implied
    // so they are left out
    float damage;

    // The Weapon constructor first calls the Item constructor
    // with the arguments from the Weapon constructor
    Weapon(float pWeight, float pValue, float pDamage) : Item(pWeight, pValue)
    {
        damage = pDamage;
    }
};

// Armour is pretty much identical

There’s nothing new in the base class, but in the derived class we specify that it inherits from Item using the public access specifier, and there’s also a small modification to the constructor. Just like inside a class, an access specifier is used when inheriting. public causes all public members in the base class to also be public in the derived class, but private members of the base class are not accessible and are not declared in the derived class. private makes all public members in the base class private in the derived class, and again the private base class members are not declared.

Now we can create an instance of the Weapon class and access its member variables which include those from the Item class.

Weapon excalibur(12.0f, 1024.0f, 24.0f);
std::cout << "Weight = " << excalibur.weight << " lbs\n";
std::cout << "Value  = " << excalibur.value << " gold coins\n";
std::cout << "Damage = " << excalibur.damage << "\n";

Member functions are also inherited, as well as member variables, but some functions are a much more interesting case.

Virtual Functions

It would be helpful in this hypothetical fantasy game if the Items could be described to the player, so we write a describe member function in the Item class which prints the weight and value of the object. It’s inherited in the Weapon class, so is callable from there too.

class Item
{
    /* Existing code */

    void describe()
    {
        std::cout << "Weight = " << weight << " lbs\n";
        std::cout << "Value  = " << value << " gold coins\n";
    }
};
// Works as expected!
exalibur.describe();

But what about the Weapon’s damage? Item doesn’t know anything about the properties of its derived classes, so we have to implement a different describe function in Weapon. We can’t do that though—unless we change the name or arguments—because a describe function inherited from Item already exists in Weapon. This is where virtual functions step in. By declaring a function to be virtual we tell the compiler that it will be redefined in a derived class, fixing the naming conflict.

virtual void describe()
{
    std::cout << "Weight = " << weight << " lbs\n";
    std::cout << "Value  = " << value << " gold coins\n";
}

And then in Weapon we write the specialised describe function.

// We don't need virtual because Weapon's describe is not being redefined
// in any class inheriting from Weapon
void describe()
{
    std::cout << "Weight = " << weight << " lbs\n";
    std::cout << "Value  = " << value << " gold coins\n";
    std::cout << "Damage = " << damage << "\n";
}

Here we’ve included the entire definition of Item::describe (the describe function in the Item class) in the definition of Weapon::describe, but this isn’t actually necessary; we can call Item::describe directly from Weapon::describe.

void describe()
{
    Item::describe();
    std::cout << "Damage = " << damage << "\n";
}

It’s worth mentioning at this point the existence of const and pure virtual functions; a const function is not a function that returns a const type (think about this for a second and you’ll see why this is mostly superfluous) but instead is one that doesn’t modify any member variables. A pure virtual function forces an entire class to be defined as abstract, which means that it cannot be instantiated itself, although any derived classes can be. The syntax for these functions is a bit different

// The describe function doesn't modify any member variables, so can be
// declared/defined as const
void describe() const
{
    /* Code */
}

// A pure virtual version
virtual void describe() = 0;

// And a const pure virtual
virtual void describe() const = 0;

Because a const function cannot modify any member variables, even by calling other member functions, they are restricted to being able to call other const member functions. The pure virtual specifier can also only be included in function definitions and not declarations, although pure virtual functions can still be defined outside of the class body.

Friendship

When first looking at classes we ran into the problem where a non-member function needed to access private members of a class, but we didn’t want to give access to anything else. To solve this we introduced two public getter functions, but there’s an alternative way using the friend keyword. Returning to the Rational class for this example,

class Rational
{
    /* Old code here */

    // Declare the operator* non-member function that acts on two rationals to
    // be a friend of this class
    friend Rational operator*(Rational lhs, Rational rhs);
};

// The function still needs to be declared and defined separately
Rational operator*(Rational lhs, Rational rhs);

By adding a declaration of a non-member function with friend in front to class definition we grant access of all private member variables to that function. operator* can therefore be rewritten as if a and b where public.

Rational operator*(Rational lhs, Rational rhs)
{
    return Rational(lhs.a * rhs.a, lhs.b * rhs.b);
}

Classes can also be defined to be friends of other classes, using similar syntax. In this way, the friend class can access all private members of the other class. Two-way access is not granted automatically however, friendship must be declared in both classes if private members are to be accessible both ways.

class Foo
{
    private:
    int a;

    public:

    Foo(int x)
    {
        a = x;
    }

    friend class Bar; // Make a accessible to bar
};

class Bar
{
    public:

    int b;

    Bar(int y)
    {
        b = y;
    }

    int sum(Foo f)
    {
        // Bar has friend access to f's private members
        return b + f.a;
    }
};

C++ also has an additional access specifier, protected, which restricts access of a class’ members to the members themselves and any friends. It is not identical to private though, as any derived class can also access the protected members, whereas private members are inaccessible to the derived class. Classes can also inherit using protected, in which case all public and protected members become protected, and all private members are inaccessible. The protected access specifier therefore grants a way of restricting access to derived classes, but not the outside world. When using public or private inheritance, protected members preserve their protected nature or become private, respectively.

Exercise

Sorry, there’s no exercise for this section!

Solution
I told you there was no exercise, go outside or something, you've probably been here too long.