include guards

Class Inheritance in C++

Class inheritance is one of the pillars of object oriented programming. Class inheritance allows us to reuse our classes by deriving new classes from old one and customizing the new classes as needed. We’ll start with an an example class, called animal.

The animal class is defined using the class keyword, followed by the class name and then a pair of matching curly braces. Within the curly braces we will define the class’s behavior and state. Classes are typically divided into two sections, a public section and a private section. The public section is defined via the public keyword followed by a colon; likewise, the private section is defined with the private keyword followed by a colon.

Class definitions typically are placed in a header file with the .h extension. We ought to surround the class definition with an include guard, which keeps the header file from being included more than once in a program. Often, we can use the preprocessor directive #pragma once to act as an include guard; however, as of this moment #pragma once is not part of the official standard, so instead we will use #ifndef followed by the #define preprocessor directives.

#ifndef ANIMAL_H
#define	ANIMAL_H

class animal {
public:
    
private:
    
};

#endif	/* ANIMAL_H */

Note that the class definition ends with a semicolon after the closing brace; this is kinda unusual, compared to other languages like Java or C#.

The behavior for the animal class is implemented in a file with the .cpp extension.

 animal.h

#ifndef ANIMAL_H
#define	ANIMAL_H

class animal {
public:
    void eat();
    void sleep();
    void breathe();
private:
    
};

#endif	/* ANIMAL_H */

 animal.cpp

#include "animal.h"
#include 

void animal::eat(){ std::cout << "Eating!" << std::endl;}
void animal::sleep() { std::cout << "Sleeping!" << std::endl;}
void animal::breathe() { std::cout << "Breathing!" << std::endl;}

We can then use this class in our main code. Each instance of the animal class should be able to do three things – eat, sleep and breathe, functions that are common to all animals.

main.cpp

#include <cstdlib>
#include "animal.h"

using namespace std;

int main(int argc, char** argv) {

    animal aardvark;
    
    aardvark.eat();
    aardvark.breathe();
    aardvark.sleep();
    
    return 0;
}

The animal class methods are pretty basic. What if we want an animal that can fly or swim? We can customize the animal class by using it as a base class for other, more specific classes.These classes will be derived from the animal base class, which means they will still have the functionality of the original animal class, plus methods all their own. To have a derived class inherit from a base class, just include a colon followed by the keyword public and then the name of the class in the derived class’s definition.

bird.h

#ifndef BIRD_H
#define	BIRD_H

#include "animal.h"

class bird : public animal{
public:
    void fly();
    void sing();
private:

};

#endif	/* BIRD_H */

bird.cpp

#include <iostream>
#include "bird.h"

void bird::fly(){std::cout << "Flying!" << std::endl;}
void bird::sing(){std::cout <<"Chirp!Chirp!" << std::endl;}

main.cpp

#include 
#include "bird.h"

using namespace std;

int main(void) {

    bird bluebird;
    
    bluebird.fly();
    bluebird.eat();
    bluebird.sing();
    bluebird.sleep();
    
    return 0;
}

Inheritance enables us to add functionality to an existing class by adding additional methods. Inheritance also allows us to add additional data members to an existing class. Finally, we can change how an existing class method works by overriding it in the derived class.

Inheritance is based on a “is-a” relationship; for example, a bird is an animal.

Members of a class can be declared private, public, or protected. Private members are not available outside of the class, public members are available outside the class, and protected members are available to classes that derive from the class.

Class methods and data members that we want to be private, but still available to classes that inherit from it, should be declared protected.

Let’s create a new base class, vehicle, that will have some actions common to all vehicles – it will start, stop, and move, and it will have a name. However, we don’t anyone to use just a generic ‘vehicle’, so in order to utilize the start(), stop() and move() methods, they will need to do so through a derived class, such as an airplane. In order to enforce this behavior, we will make the start(), stop() and move() methods protected.
vehicle.h

#ifndef VEHICLE_H
#define	VEHICLE_H
#include 

class vehicle {
public:
    std::string GetName();
protected:
    void Move();
    void Start();
    void Stop();
private:
    std::string _name;
};

#endif	/* VEHICLE_H */

vehicle.cpp

#include "vehicle.h"
#include 
#include 

std::string vehicle::GetName() {return this->_name; }
void vehicle::Move() {std::cout << "Moving!" << std::endl; }
void vehicle::Start() {std::cout << "Starting!" << std::endl;}
void vehicle::Stop() {std::cout << "Stopping!" << std::endl;}
   
void Stop();

Now let’s create a derived class called car. The car class will have its own private data member, _numberOfWheels, as well as its own public methods, such as driveTheCar(), startTheCar() and stopTheCar().
car.h

#ifndef CAR_H
#define	CAR_H

#include "vehicle.h"

class car : public vehicle {
public:
    int getNumberOfWheels();
    void driveTheCar();
    void startTheCar();
    void stopTheCar();
private:
    int _numberOfWheels;
    
};

#endif	/* CAR_H */

car.cpp

#include <iostream>
#include "car.h"

int car::getNumberOfWheels(){return this->_numberOfWheels;}

void car::driveTheCar(){
    std::cout << "Pressing the gas." << std::endl;
    Move();
}
void car::startTheCar(){
    std::cout << "Turning the car on." << std::endl;
    Start();
}

void car::stopTheCar(){
    std::cout << "Pressing the break." << std::endl;
    Stop();
}

main.cpp

#include "car.h"

int main(void) {

    car theCar;
    
    theCar.startTheCar();
    theCar.driveTheCar();
    theCar.stopTheCar();
    
    return 0;
}

Unfortunately, we do not actually have methods to set either the vehicle’s name or the number of wheels for the car. Let’s use the class constructor to do this.

If a base class does not have an explicitly defined constructor, its default constructor is called each time we create an object of a class derived from that class. However, if a base class has an explicit constructor, we need to add a list of initializers to the derived class’s constructor, that way we can pass arguments back to base class constructors.
car.h

#ifndef CAR_H
#define	CAR_H
#include <iostream>
#include "vehicle.h"

class car : public vehicle {
public:
    //constructor
    car(std::string carName, int numWheels);
    int getNumberOfWheels();
    void driveTheCar();
    void startTheCar();
    void stopTheCar();
private:
    int _numberOfWheels;
    
};

#endif	/* CAR_H */

car.cpp

#include <iostream>
#include "car.h"

car::car(std::string carName, int numWheels) : vehicle(carName){
    this->_numberOfWheels = numWheels;
}

int car::getNumberOfWheels(){return this->_numberOfWheels;}

void car::driveTheCar(){
    std::cout << "Pressing the gas." << std::endl;
    car:Move();
}
void car::startTheCar(){
    std::cout << "Turning the car on." << std::endl;
    Start();
}

void car::stopTheCar(){
    std::cout << "Pressing the break." << std::endl;
    Stop();
}

main.cpp

#include <iostream>
#include "car.h"

using namespace std;

int main(void) {

    car theCar("Toyota", 4);
    
    cout << "The car is a " << theCar.GetName() << " and has " << theCar.getNumberOfWheels() << " wheels." << endl;
    
    theCar.startTheCar();
    theCar.driveTheCar();
    theCar.stopTheCar();
    
    return 0;
}


If you’re interested, please check out my book http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M