Overview
Teaching: 10 min
Exercises: 5 minQuestions
What is inheritance?
What is inheritance used for?
Objectives
Create a derived class specialized for 3D vectors
We have so far been using our Vector
class to store some number of integers. However, what if we instead wanted to have a vector that we could use for 3D positions, would we have to build a new class to do this from scratch or could we somehow reuse what we have already done for our more general Vector
class? The answer is yes we can reuse much of what we have already done, and we can do that using inheritance.
As a starting point let’s copy our previous program.
$ cp operator.cpp inheritance.cpp
$ nano inheritance.cpp
Then modify it to add a new class Vec3
which inherits our previous Vector
class. Another way of saying this is that the Vec3
class is a derived class from the base class Vector
. You can specify that one class will inherit another class’s member variables and functions by adding a :
after the new class name in the class declaration followed by an access method public
, private
or protected
and then the name of the class to be inherited.
Types of inheritance access modifiers:
public
: base class’s public and protected members are public and protected in the derived class respectively.protected
: base class’s public and protected members are protected and protected in the derived class respectively.private
: base class’s public and protected members are private and private in the derived class respectively.Private members in the base class are not accessible in the derived class. Exceptions to this can arise if using friend declarations, which we will not cover.
For more details about types of inheritance see this cppreference.com page.
#include <iostream>
class Vector{...};
class Vec3:public Vector{
public:
Vec3():Vector(3){
};
};
int main(){
Vec3 a;
a.data[0]=1;
a.data[1]=2;
a.data[2]=3;
a.display();
}
We also added a default constructor Vec3()
which calls the constructor from the base class with a size of 3
specified, Vector(3)
.
Our new Vec3
class can be thought of as a combination of the two class declarations. First the original Vector
class, then with the changes added for the Vec3
class.
$ g++ inheritance.cpp -o inheritance
$ ./inheritance
Vector: size=3, contents=(1,2,3)
Now that our Vec3
class is explicitly 3 elements long, it seems a little redundant to display the size as 3, also it still says Vector
but now it is a Vec3
. Lets create a new display
member function for our Vec3
class.
$ nano inheritance.cpp
#include <iostream>
class Vector{...};
class Vec3:public Vector{
public:
Vec3():Vector(3){};
void display(){
std::cout<<"Vec3: ("<<data[0]<<","<<data[1]<<","<<data[2]<<")\n";
}
};
int main(){
Vec3 a;
a.data[0]=10;
a.display();
}
The new display
member function declared in the Vec3
class will now replace the Vector
class’s display
member function for Vec3
objects.
Lets build and run it to see the results.
$ g++ inheritance.cpp -o inheritance
$ ./inheritance
Vec3: (10,0,0)
Multiple inheritance
C++ allows multiple inheritance, which means a class can have multiple base classes. For example:
#include <iostream> class A{ public: A(){std::cout<<"A constructor called\n";} }; class B{ public: B(){std::cout<<"B constructor called\n";} }; class C: public B, public A{//Note the order public: C(){std::cout<<"C constructor called\n";} }; int main(){ C c; }
$ g++ multiple_inheritance.cpp -o multiple_inheritance $ ./multiple_inheritance
B constructor called A constructor called C constructor called
Base class constructors are called in the order they are listed in the class’s inheritance list.
Private inheritance
... 72 class Vec3:private Vector{ 73 public: 74 Vec3():Vector(3){ 75 }; 76 void display(){ 77 std::cout<<"Vec3: ("<<data[0]<<","<<data[1]<<","<<data[2]<<")\n"; 78 } 79 }; 80 81 int main(){ 82 Vec3 a; 83 a.data[0]=10; 84 a.display(); 85 }
If we take the most recent version of
inheritance.cpp
and copy it toprivate_inheritance.cpp
and only change line 72 fromclass Vec3:public Vector{
toclass Vec3:private Vector{
what will happen when we try to compile it?
It will compile fine.
Generate the following errors:
private_inheritance.cpp: In member function ‘void Vec3::display()’: private_inheritance.cpp:77:27: error: ‘int* Vector::data’ is private within this context 77 | std::cout<<"Vec3: ("<<data[0]<<","<<data[1]<<","<<data[2]<<")\n"; | ^~~~ private_inheritance.cpp: In function ‘int main()’: private_inheritance.cpp:83:5: error: ‘int* Vector::data’ is private within this context 83 | a.data[0]=10; | ^~~~
Generate the following error:
private_inheritance.cpp: In function ‘int main()’: private_inheritance.cpp:83:5: error: ‘int* Vector::data’ is private within this context 83 | a.data[0]=10; | ^~~~
Solution
NO: private inheritance causes the derived class to inherit the base classes members as private members. In the main function the inherited member
data
is accessed which is not allowed and would generate a compiler error.NO: While it is correct that it will generate a compiler error similar to this, the class member function
display
can access its own private members. Since thedata
member ispublic
in the base class it will be inherited as aprivate
member in the derived class.YES:
data
will be inherited as a private member in the derived class and as such can not be accessed outside class member functions.
Key Points
Inheritance allows reuse of code in related classes.
Inheritance can happen in one of three ways
public
,protected
orprivate
and affects how the inherited members are accessed in the derived class.