Friday, 6 March 2015

Inheritance and access specifiers

Inheritance and access specifiers with examples:

There are three types of inheritances available in inheritance.

Types of Inheritance
We have seen there are three types of access specifiers in C++.

 Like that there are three types of access specifiers available for inheritance. See the above diagram.
As we know that the public members can be accessed by anyone, and the private members can only be accessed by member functions of the same class.

Let us see the simple example to understand quickly about the access specifiers:
class AceessSpecifiers
{
private:
    int m_iValPrivate; // can only be accessed by AceessSpecifiers member functions (not derived classes)

public:
    int m_iValPublic; // can be accessed by anybody

protected:
    int m_iValProtected; // can be accessed by derived class
};

In the above code

m_iValPrivate – This can only be accessed by AceessSpecifiers member functions (notderived classes)

m_iValPublic – This can be accessed by anybody

m_iValProtected – This can be accessed by derived class

Now I am providing the complete example to understand these access specifiers of each:
class AceessSpecifiers
{
private:
    int m_iValPrivate;

public:
    int m_iValPublic;

protected:
    int m_iValProtected;
};

class DerivedCalss: public AceessSpecifiers

{
public:
    DerivedCalss ()
    {
        m_iValPublic = 10;
        // m_iValPrivate = 22; 
        m_iValProtected = 53;
      }
};
int main()
{
    AceessSpecifiers ocAcess;
    ocAcess.m_iValPublic = 1;

  //   ocAcess.m_iValPrivate = 2; 
  //  ocAcess.m_iValProtected = 3

    DerivedCalss ocDerived;

   // ocDerived.m_iValProtected;
    ocDerived.m_iValPublic;
    getchar ();
    return 0; 
} 

 In the above example

m_iValPublic = 10 -  allowed: can access public base members from DerivedCalss class
m_iValPrivate = 22 - not allowed: can not access private base members from DerivedCalss class
m_iValProtected = 53 - allowed: can access protected base members from DerivedCalss class

ocAcess.m_iValPublic = 1 - allowed: can access public members from outside class
ocAcess.m_iValPrivate = 2 - not allowed: cannot access private members from outside class
ocAcess.m_iValProtected = 3 - not allowed: cannot access protected members from outside class

How to inherit the base class using different access specifiers. Look at the below pseudo code
class AceessSpecifiers
{
private:
    int m_iValPrivate; // can only be accessed by AceessSpecifiers member functions (not DerivedCalss classes)

public:
    int m_iValPublic; // can be accessed by anybody

protected:
    int m_iValProtected; // can be accessed by DerivedCalss calss
};
  // Inherit from AceessSpecifiers publicly

class Derived_Pub: public AceessSpecifiers
{
};

// Inherit from AceessSpecifiers privately
class Derived_Pri: private AceessSpecifiers
{
};

// Inherit from AceessSpecifiers protectedly
class Derived_Pro: protected AceessSpecifiers
{
}; 

In the class default access specifier is private, like that only the default inheritance is also private.
// Defaults to private inheritance
{
class Derived_Def: AceessSpecifiers
};

There are three ways that members can be accessed:

A class can always access its own members regardless of access specifier.
The public accesses the members of a class based on the access specifiers of that class.
A derived class accesses inherited members based on the access specifiers of its immediate parent. A derived class can always access its own members regardless of access specifier.

Now look at each inheritance type:

Public inheritance:

Public inheritance is by far the most commonly used type of inheritance. In fact, very rarely will you use the other types of inheritance, so your primary focus should be on understanding this section. Fortunately, public inheritance is also the easiest to understand. When you inherit a base class publicly, all members keep their original access specifications. Private members stay private, protected members stay protected, and public members stay public.
class AceessSpecifiers
{
private:
    int m_iValPrivate; // can only be accessed by AceessSpecifiers member functions (not DerivedCalss classes)

public:
    int m_iValPublic; // can be accessed by anybody

protected:
    int m_iValProtected; // can be accessed by DerivedCalss calss
};

  // The derived class always uses the immediate parent's class access specifications
class Derived_Pub: public AceessSpecifiers
{
  Derived_Pub ()
    {

        // Thus, Pub uses Base's access specifiers
        m_iValPublic = 1; // the anybody can access public members

       // m_iValPrivate = 2;     
       m_iValProtected = 3; // the derived classes can access protected members
    }
};
This is fairly straightforward. The things worth noting are:

1. Derived classes cannot directly access private members of the base class.
2. The protected access specifier allows derived classes to directly access members of the base class while not exposing those members to the public.
3. The derived class uses access specifiers from the base class.
4. The outside uses access specifiers from the derived class.

To get the idea quickly see the below table helps us to understand more, please see below table.
Public Inhetitance
Access specifier for Base class
Access specifier for Derived class
Derived class accesses the members of the base?
Is it access publically?
Public
Public
Yes
Yes
Private
Private
No
No
Protected
Protected
Yes
No

Private inheritance:

With private inheritance, all members from the base class are inherited as private. This means private members stay private, and protected and public members become private.

Note that this does not affect that way that the derived class accesses members inherited from its parent! It only affects the code trying to access those members through the derived class.
#include "stdafx.h"
#include <iostream>
#include <memory>
using namespace std;
class AceessSpecifiers
{
private:
    int m_iValPrivate; // can only be accessed by AceessSpecifiers member functions (not DerivedCalss classes)

public:
    int m_iValPublic; // can be accessed by anybody

protected:
    int m_iValProtected; // can be accessed by DerivedCalss calss

};

// Inherit from AceessSpecifiers privately
class Derived_Pri: private AceessSpecifiers

{
    Derived_Pri ()
    {
        m_iValPublic = 1; 

      //  m_iValPrivate = 2; 
        m_iValProtected = 3; 
    }
};
int main ()
{
    Derived_Pri ocPri;

    ocPri.m_iValPublic = 1; 

    //ocPri.m_nPrivate = 2; 

    ocPri.m_iValProtected = 3;

    AceessSpecifiers ocBase;

    ocBase.m_iValPublic = 1; 

    //ocBase.m_nPrivate = 2; 

    ocBase.m_iValProtected = 3; 
}

Here in the above code,

  m_ iValPublic becomes private
  m_nPrivate stays private
  m_iValProtected becomes private

See the below table format for quick reference about the private inheritance
Private Inhetitance
Access specifier for Base class
Access specifier for Derived class
Derived class access the members of the base?
Is it access publically?
Public
Private
Yes
No
Private
Private
No
No
Protected
Private
Yes
No

Protected inheritance:

Protected inheritance is the last method of inheritance. It is almost never used, except in very particular cases. With protected inheritance, the public and protected members become protected, and private members stay private.

To summarize in table form:
protected Inhetitance
Access specifier for Base class
Access specifier for Derived calss
Derived class access the members of the base?
Is it access publically?
Public
Protected
Yes
No
Private
Private
No
No
Protected
Protected
Yes
No

Protected inheritance is similar to private inheritance. However, classes derived from the derived class still have access to the public and protected members directly. The public (stuff outside the class) does not.

Please see Virtual Inheritance for more information.

No comments: