Riley Miller

C++ Inheritance: Inheritance Access Levels (Pt. 3)

July 06, 2020

C++ Member Access Levels

With the three member access levels for classes, it is easy to get them confused and to understand the limitations and meaning behind each access level.

KeywordMeaning
publicAccessible everywhere
protectedAccessible by self and derived classes
privateAccessible by self

Inheritance Access Levels

A common point of confusion for the (public|protected|private) keywords is understanding what they mean within the context of describing member access level versus the inheritance relationship between a derived class and a base class. Using our example, when public is used during class definition like in:

1class Wumpus : public Monster {
2 // Wumpus definition
3}
4

public actually describes the inheritance between Wumpus and Monster. Specifically, when public is used during class definition, it is specifying that all public class members of Monster are accessible as public class members of Wumpus and that all protected class members of Monster are also accessible as protected class members of Wumpus.

When learning inheritance, you will typically see public used to describe the inheritance relationship between derived and base classes. However, both private and protected can be used to describe the inheritance relationship as well.

For example, when protected is used to describe the inheritance relationship, the public and protected members of the base class are accessible only as protected members of the derived class.

1// The Base Class
2class Monster {
3 public:
4 int screams = 0;
5
6 void setHealth(int hearts) {
7 this->hearts = hearts;
8 }
9
10 int getHealth() {
11 return this->hearts;
12 }
13
14 protected:
15 int hearts;
16}
17
18
19// Derived Class
20class Wumpus : protected Monster {
21 public:
22 void Hide() {
23 cout << "Shhhhhhh" << endl;
24 this->screams = 0;
25 this->isVisible = false;
26 }
27
28 void Appear() {
29 cout << "ARGHHARHGHHHH" << endl;
30 this->screams = this->screams + 1;
31 this->isVisible = true;
32 }
33
34 private:
35 bool isVisible;
36}
37
38int main() {
39 Monster base;
40 Wumpus derived;
41
42 cout << "Monster screams: " << base.screams << endl; // No Error
43
44 derived.Hide() // No Error
45
46 cout << "Wumpus screams: " << derived.screams << endl; // Error
47 return 0;
48}
49

Now that the inheritance relationship of Wumpus is described as protected instead of public, the int screams public member of Monster is only accessible as a protected member on Wumpus.

In the code snippet above, you can see that calling the Hide() method on Wumpus doesn’t throw any errors because screams is modified within Wumpus. However, when trying to access screams on the Wumpus object within the scope of main(), the compiler will throw an error complaining about accessing a protected attribute.

When describing the inheritance relationship, public, protected, and private mean:

KeywordMeaning
publicpublic and protected members of the base class are accessible correspondingly as public and protected members of the derived class
protectedpublic and protected members of the base class are accessible correspondingly as protected members of the derived class
privatepublic and protected members of the base class are accessible correspondingly as private members of the derived class

It is also noteworthy that if the inheritance relationship is not explicitly described, it will default to private. Example:

1class Wumpus : Monster {
2 // Wumpus class definition
3}
4

Using the class definition above, the public and protected members of Monster will only be accessible as private on Wumpus.

C++ Inheritance Articles


Written by Riley Miller, follow me on Twitter 🐦

//