
Inheritance
So far, we have only dealt with freestanding classes, let us now put three classes together in a class hierarchy. We start with the baseclass Person
, which has a constructor that initializes the field m_stName
, and a method Print
that writes the name. Print
is marked as virtual; this means that dynamic binding will come into effect when we, in the main
function, define a pointer to an object of this class. We do not have to mark the methods as virtual in the subclasses, it is sufficient to do so in the baseclass. The constructors of a class cannot be virtual. However, every other member, including the destructor, can be virtual and I advise you to always mark them as virtual in your baseclass. Non-virtual methods are not a part of the object-oriented model and were added to C++ for performance reasons only.
Person.h
class Person { public: Person(string stName); virtual void Print() const; private: string m_stName; };
Person.cpp
#include <iostream> #include <string> using namespace std; #include "Person.h" Person::Person(string stName) :m_stName(stName) { // Empty. } void Person::Print() const { cout << "Name: " << m_stName << endl; }
Student
and Employee
are subclasses to Person
, which means that they inherit all public members of Person
. Generally, they also inherit all protected members, even though we do not have any of those in the baseclass in this case. They define their own versions of Print
with the same parameter list (in this case no parameters at all). It is called overriding. This is not to be confused with overloading, which was refers to freestanding functions or methods of the same class. For overriding to come into effect, the methods must have the same name and parameters list and the method of the baseclass must be virtual. As constructors cannot be virtual, they cannot be overridden. Two overridden methods cannot have different return types.
Student.h
class Student : public Person { public: Student(string stName, string stUniversity); void Print() const; private: string m_stUniversity; };
Student.cpp
#include <iostream> #include <string> using namespace std; #include "Person.h" #include "Student.h" Student::Student(string stName, string stUniversity) :Person(stName), m_stUniversity(stUniversity) { // Empty. } void Student::Print() const { Person::Print(); cout << "University: " << m_stUniversity << endl; }
Employee.h
class Employee : public Person { public: Employee(string stName, string stEmployer); void Print() const; private: string m_stEmployer; };
Employee.cpp
#include <iostream> #include <string> using namespace std; #include "Person.h" #include "Employee.h" Employee::Employee(string stName, string stEmployer) :Person(stName), m_stEmployer(stEmployer) { // Empty. } void Employee::Print() const { Person::Print(); cout << "Company: " << m_stEmployer << endl; }