The inheritance mode sits in the declaration class child : <mode> parent; it controls how the parent’s members are demoted for outsiders.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>

class Base {
public:
int pub = 1;

protected:
int prot = 2;

private:
int priv = 3;
};

// Whether a super-class member is accessible inside child-class or not is solely
// determined by super-class access level. Therefore, the child-class of any
// inheritance mode can access pub and prot.

// In contrast, the inheritance mode demotes super-class members: the effective
// access is the stricter of the member's level and the mode's level
// (public > protected > private), applied only to outsiders (external code and
// further derived classes).
//
// Base member level | PUBLIC inherit | PROTECTED inherit | PRIVATE inherit
// ------------------+----------------+-------------------+----------------
// public public protected private
// protected protected protected private
// private private private private
//
// 1) PUBLIC: access levels pass through unchanged.
class Pub : public Base {
public:
void inside() {
std::cout << pub << prot; // OK: pub public, prot protected
// priv; // ERROR: private in Base
}
};

// 2) PROTECTED: Base's public members demoted to protected.
class Prot : protected Base {
public:
void inside() {
std::cout << pub << prot; // OK: both protected now
}
};

// 3) PRIVATE: everything collapses to private in Priv.
class Priv : private Base {
public:
void inside() {
std::cout << pub << prot; // OK: private in Priv, visible here
}
};

int main() {
Pub p;
(void)p.pub; // OK: public
// p.prot; // ERROR: protected

Prot t;
// t.pub; // ERROR: demoted to protected

Priv v;
// v.pub; // ERROR: demoted to private
}