private inheritance

private is used in the line where the derived class declares its inheritance from a base class.

syntax
1
2
3
4
5
6
7
8
9
class Base
{
//...base class members and methods
}

class Derived : private Base
{
//...derived class members and methods
}

e.g. a class Car related to class Motor via private inheritance. demolist10_8

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
#include <iostream>
using namespace std;

class Motor
{
public:
void SwitchIgnition()
{
cout << "ignition on" << endl;
}
void PumpFuel()
{
cout << "fuel is cylinder" << endl;
}
void FireCyliners()
{
cout << "Vroooom" << endl;
}
};
class Car : private Motor
{
public:
void Move()
{
SwitchIgnition();
PumpFuel();
FireCyliners();
}
};

int main()
{
Car DreamCar;
DreamCar.Move();

return 0;
}

line 23-28 demonstrates that inside the class and derived class, private heritance, class Car has access to the base class Motor, on the other hand, in main() a object of derived class Car via private heritance can't invoke methods(members) of base class Motor directly. For instance, if method SwitchIgnition was invoked like DreamCar.SwitchIgnition(), compared with line 33-34, error will appear as cannot access base's public member.

additionally, inside main() error happens when using DreamCar.Car::SwitchIgnition.

protected inheritance

Q

:does a derived class can be derived from two or more base class?

A

:you can derive a class from any number of base classes. Deriving a class from more than one direct base class is called multiple inheritance. e.g.:

1
2
3
4
class A { /* ... */ };
class B { /* ... */ };
class C { /* ... */ };
class X : public A, private B, public C { /* ... */ };

protected inheritance is similar to private inheritance in the following ways:

  1. it also signifies a has-a relationship.
  2. derived class accesses all public and protected members of base class
  3. those outside the inheritance hierarchy with an instance of derived can't access public member of base, like implementation in main().

the differences lies in following:

1
2
3
4
class Derived2 : protected Derived
{
//...can access protected and public members of base
}

protected inheritance hierarchy allow the subclass of the subclass access to protected and public members of base, but that can't happen for private inheritance hierarchy.

using protected inheritance demolist10_9

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
#include <iostream>
using namespace std;

class Motor
{
public:
void SwitchIgnition()
{
cout<<"ignition on"<<endl;
}
};

class Car:protected Motor
{
public:
void CarMove()
{
SwitchIgnition();
cout<<"carmove"<<endl;
}
};

class RaceCar:protected Car
{
public:
void CarMove()
{
SwitchIgnition();
cout<<"racecarmove"<<endl;
}
};

int main()
{
RaceCar Lafferi;
Lafferi.CarMove();

return 0;
}

Note that: using protected or public inheritance only when you have to.

having an instance of Motor as a private member instead of inheriting from it (indicate Motor) is called aggregation or composition.

e.g.

1
2
3
4
5
6
7
8
9
10
11
class Car
{
private:
Motor heartofCar;

public:
void Move()
{
heartofCar.SwitchIgnition();
}
}

This can be good design as it enables you to easily add more motors as members attributes to an existing class Car.

The problem of slicing

Slicing happens when code like:

1
2
Derived objDerived;
Base objectBase = objDerived

or alternatively,

1
2
3
4
void UseBase(Base Input);
...
Derived objDerived;
UseBase(objDerived);

In both case, the object of type Derived is being copied into another of type Base, either explicitly via assignment or by passing as an argument. That will cause unwanted reduction of data.

To avoid slicing problem, don't pass parameter by value. Pass it as pointers to the Base class or reference to the same.

multiple inheritance

A class derives from two or more base classes.

Syntax

:

1
2
3
4
class Derived: access-specifier Base1, access-specifier Base2
{
//class members
}

A manifestation of Platypus that demonstrates multiple inheritance is demonstrated by the following.demolist10_10

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
#include <iostream>
using namespace std;

class BaseClass1
{
public:
void BaseFunction1()
{
cout << "base class -1" << endl;
}
};
class BaseClass2
{
public:
void BaseFunction2()
{
cout << "base class -2" << endl;
}
};
class BaseClass3
{
public:
void BaseFunction3()
{
cout << "base class -3" << endl;
}
};
class DerivedClass : public BaseClass1, public BaseClass2, public BaseClass3
{
public:
void DerivedFunction()
{
cout << "Derived class" << endl;
}
};

int main()
{
DerivedClass objDerived1;
objDerived1.DerivedFunction();
objDerived1.BaseFunction1();
objDerived1.BaseFunction2();
objDerived1.BaseFunction3();

return 0;
}
Analysis

: class DerivedClass is able to invoke the three characteristics of the individual base classes using an object of DerivedClass which is named objDerived1.

avoiding inheritance using final

It's used to ensure that a class declared as final can't be used as a base class. A version of class DerivedClass taken from demolist10_10 and declared as final would look like this:

1
2
3
4
5
6
7
8
class DerivedClass final: public BaseClass1, public BaseClass2, public BaseClass3
{
public:
void DerivedFunction()
{
//...implementation
}
}

The public inheritance is an is-a relationship between base class and derived class, whereas private and protected inheritance create has-a relationship