Inheritance is a type of relationship. It involves sharing of attributes and operations among classes
A base class defines a set of common attributes and operations which it shares with derived classes. 
A derived class extends the resources provided by the base class by adding its own data members and member functions
For example,

Inheritance
    - combines with object composition to create the primary techniques for reusing software
    - involves a class hierarchy whose elements are base and derived classes. 
    - A base class provides member functions and data to a derived class. 
    - The derived class might choose to add its own member functions or redefine existing ones in the base class. 

General Form of Derived Class:
    class derived-class-name:access base-class-name
    {
        //...
    }
    where access is one of three keywords:
      public, private, or protected.

  • When the access specifier for the inherited base class is public

  • all public members of the base class become public members of the derived class.
  • When the access specifer is private

  • all public members of the base class become private members of the derived class.
  • In either case, any private members of the base remain private to it and are inaccessible by the derived class.
    • In order to ONLY let the derived class (other than the base class) to access, the base class needs to specify its members as protected instead of private.
  • For the protected members of base class, if inherit access is
    • public - they become protected members of the derived class.
    • private - they become private members of the derived class.
    • protected - they become protected members of the derived class.
  • The public members of base class become protected members of the derived class when the inherited method is protected.  
Example 1: Inherit as public.
#include <iostream>
using namespace std;

class base {
 int x;
public:
 void setx(int n) { x = n; }
 void showx() { cout << x <<'\n'; }
};

//Inherit as public.
class derived : public base {
 int y;
public:
 void sety(int n) { y = n; }
 void showy() { cout << y << '\n'; }
};

void main()
{
 derived ob;

 ob.setx(10);  // access member of base class
 ob.sety(20);  // access member of derived class

 ob.showx();  // access member of base class
 ob.showy();  // access member of derived class

/* Although it is inherited as public, it can not access 
   private mewmber.  The following is illegal.
   cout << ob.x <<endl;
*/
}

Exampler 2: Inherit as private.
#include <iostream>
using namespace std;

class base {
 int x;
public:
 void setx(int n) { x = n; }
 void showx() { cout << x <<'\n'; }
};

//Inherit as private.
//Access setx() and showx() from within derived class.
class derived : private base {
 int y;
public:
 void setxy(int n, int m) { setx(n); y = m; }
 void showxy() { showx(); cout << y << '\n'; }
};

void main()
{
 derived ob;

 /*  setx() becomes private to derived class.
 Therefore the following are illegal.
  ob.setx(10); 
  ob.showx(); 
 */
 ob.setxy(10, 20);
 ob.showxy();
}

Example 3: Inherit as public with protected members in base.
#include <iostream>
using namespace std;

class base {
protected:    // private to base
 int a, b;    // but still accessible by derived 
public:
 void setab(int n, int m) { a = n;  b = m; }
};

class derived : public base {
 int c;
public:
 void setc(int n) { c = n; }
 // this function has access to a and b from base
 void showabc() { 
  cout << a << ' ' << b << ' ' << c << '\n'; 
 }
};

void main()
{
 derived ob;

 /*  a and b are not accessible here because they are
     private to both base and derived
  the following is illegal.
  cout << ob.a << endl;
 */
 ob.setab(1, 2);
 ob.setc(3);

 ob.showabc();
}

Example 4: Inherit as protected with protected members in base.
#include <iostream>
using namespace std;

class base {
protected:       // private to base
 int a, b;    // but still accessible by derived 
public:
 void setab(int n, int m) { a = n;  b = m; }
};

class derived : protected base {
 int c;
public:
 void setc(int n) { c = n; }
 // this function has access to a and b from base
 void showabc() { 
  cout << a << ' ' << b << ' ' << c << '\n'; 
 }
};

void main()
{
 derived ob;

 /*  setab() is not accessible here because it is
     protected from derived.
  the following is illegal.
  setab(1, 2);
 */
 ob.setc(3);

 ob.showabc();
}

Constructors, Destructors, and Inheritance
When a base class and a derived class both have constructor and destructor functions, the constructor functions are executed in order of derivation.  The destructor functions are executed in reverse order.

Example:

#include <iostream>
using namespace std;

class base {
public:
 base() { cout << "Constructing base class\n"; }
 ~base() { cout << "Destructing base class\n"; }
};

class derived : public base {
public:
 derived() { cout << "Constructing derived class\n"; }
 ~derived() { cout << "Destructing derived class\n"; }
};

void main()
{
 derived ob;
}

The program displays the following output:
Constructing base class
Constructing derived class
Destructing derived class
Destructing base class
Passing Arguments from derived constructor to base constructor:
Example:
#include <iostream>
using namespace std;

class base {
 int i;
public:
 base(int n)
  cout << "Constructing base class\n";
  i = n;
 }
 ~base() { cout << "Destructing base class\n"; }
 void showi() { cout << i << '\n'; }
};

class derived : public base {
 int j;
public:
 derived(int n, int m) : base(m) { //pass arg to base class
  cout << "Constructing derived class\n"; 
  j = n;
 }
 ~derived() { cout << "Destructing derived class\n"; }
 void showj() { cout << j << '\n'; }
};

void main()
{
 derived ob(10, 20);
 ob.showi();
 ob.showj();
}

Output:
Constructing base class
Constructing derived class
20
10
Destructing derived class
Destructing base class
Multiple Inheritance:
 
Create a multilevel class hierarchy
indirect base class -> base class -> derived class
Combine two or more base classes
to create a derived class

Virtual Base Classes:
 
This causes ambiguity when a member of Base is used by Derived3.
Since two copies of Base are included in Derived3, is a reference to a member of Base referring to the Base inherited indirectly through Derived1 or to the Base inherited indirectly through Derived2?

Solution: Use a virtual base class to prevent two copies of base from being present in derived3.
Example:

#include <iostream>
using namespace std;

class base {
public:
 int i;
};

// Inherit base as virtual.
class derived1 : virtual public base {
public:
 int j;
};

// Inherit base as virtual here, too.
class derived2 : virtual public base {
public:
 int k;
};

/* Here, derived3 inherits both derived1 and derived 2.
   However, only one copy of base is present.
*/
class derived3 : public derived1, public derived2 {
public:
 int product() { return i * j * k; }
};

void main()
{
 derived3 ob;

 ob.i=10;  // unambiguous because only one copy present
 ob.j=3;
 ob.k=5;

 cout << "Product is " <<ob.product() << '\n';
}