Inheritance C++
Inheritance C++
Feature C
Feature A
Derived class
Feature B
Defined in base class
Feature C
Protected access specifier and its role in inheritance:(Imp)
The private and protected access specifiers has same
effect in a class however their difference is seen in case of
inheritance only. The protected members are visible to
derived class however private members are not. The
purpose of making data member (s) as protected in a class
is to make such members accessible to derived class
functions.
Syntax of derived class declaration:
class Derived_class_name : visibility mode Base_class_name
{
//Body of derived class
}
The colon(:) after the Derived_class_name indicates that the
new class is created from the existing one. Here visibility
mode specifies either public or private or protected.
Visibility mode and its effect in inheritance:
Only the public and protected members of a class gets
inherited in a derived class while private members of a class
are not inherited.
Inheritable public Inheritable Private members of
members of a base protected members a base class are not
Visibility Mode class in a derived of a base class in a inherited in a
class becomes derived class derived class
becomes
public public protected
For Example:
class A
{…};
class B:public A
{…};
Example Program:
#include<iostream>
using namespace std;
class employee
{
protected:
char name[20];
float salary;
public:
void input( )
{
cout<<“Enter the name of an employee:”<<endl;
cin>>name;
cout<<“Enter the salary of an employee:”<<endl;
cin>>salary;
}
void display( )
{
cout<<“Name of an employee=“<<name<<endl;
cout<<“Salary of an employee=“<<salary<<endl;
}
};
class manager: public employee
{
protected:
char title[20];
public:
void input( )
{
employee::input( );
cout<<“Enter the title of a manager:”<<endl;
cin>>title:}
void display( )
{
employee::display( );
cout<<“The title of a manager=“<<title<<endl;
}
};
int main( )
{
manager m1,m2;
m1.input( );
m2.input( );
m1.display( );
m2.display( );
return 0;
}
2)Multiple Inheritance:
The type of inheritance in which there are multiple(more than one) base
classes and a single derived class is called multiple inheritance.
The syntax of multiple inheritance is :
class base1
{………..};
class base2
{………..};
.
.
class base n For Example:
{…………}; class A
class derived:visibility_mode base1,visibility_mode base2,… {…};
visibility_mode base n class B
{………….}; {…};
class C:public A, public B
{…};
Example program:
#include<iostream>
using namespace std;
class Base1
{
protected:
int x;
public:
void get_x( )
{
cout<<“Enter the value to x of Base1:”<<endl;
cin>>x;
}
void display_x( )
{
cout<<“The value to x of Base1=“<<x<<endl;
} };
class Base2
{
protected:
int y;
public:
void get_y( )
{
cout<<“Enter the value to y of a Base2:”<<endl;
cin>>y;
}
void display_y( )
{
cout<<“The value to the y of a Base2=“<<y<<endl;
}
};
class derived: public Base1,public Base2
{
protected:
int z;
public:
void get_z( )
{
cout<<“Enter the value to z of a derived class:”<<endl;
cin>>z;
}
void display_z( )
{
cout<<“The value to the z of a derived class=“<<z<<endl;
}
void display( )
{
cout<<“The sum is:”<<x+y+z<<endl;
} };
int main( )
{
derived d;
d.get_x( );
d.get_y( );
d.get_z( );
d.display_x( );
d.display_y( );
d.display_z( );
d.display( );
return 0;
}
Ambiguity and its resolution in multiple inheritance(Imp):
In multiple inheritance there are multiple base classes and
a single derived class. If multiple base classes have same
members(either data member or member function) name
which are being inherited to derived class and when we
access those members by using the object of a derived
class then the compiler becomes confused to use which
version of the member and of which base class and this is
called an ambiguity in multiple inheritance.
In order to resolve this problem while invoking the same
members name which are in more than one base classes
we use class name and scope resolution operator while
invoking those members.
Example program:
#include<iostream>
using namespace std;
class Base1
{
protected:
int x;
public:
void get_x( )
{
cout<<“Enter the value to x of a Base1:”<<endl;
cin>>x;
}
void display_x( )
{
cout<<“The value to x of Base1=“<<x<<endl;
}
};
class Base2
{
protected:
int x;
public:
void get_x( )
{
cout<<“Enter the value to x of a Base2:”<<endl;
cin>>x;
}
void display_x( )
{
cout<<“The value to x of a Base2=“<<x<<endl;
}
};
class derived:public Base1,public Base2
{
protected:
int z;
public:
void get_z( )
{
cout<<“Enter the value to z of a derived class:”<<endl;
cin>>z;
}
void display_z( )
{
cout<<“The value to the z of a derived class=“<<z<<endl;
}
void display( )
{
cout<<“The sum is:”<<Base1::x+Base2::x+z<<endl;
}
};
int main( )
{
derived d;
//d.get_x( );error
d.Base1::get_x( );
//d.display_x( );error
d.Base1::display_x( );
d.Base2::get_x( );
d.Base2::display_x( );
d.get_z( );
d.display_z( );
d.display( );
return 0;
}
3)Multilevel Inheritance:
The type of inheritance in which derived class is formed from
already derived class is called multilevel inheritance. The transitive
nature of inheritance is shown by multilevel inheritance.
General form(syntax):
class base
{……..};
For Example:
class derived1:visibility_mode base
{………..}; class A
{…};
class derived2:visibility_mode derived1
class B:public A
{………….};
{…};
class C:public B
{…};
Example Program:
#include<iostream>
using namespace std;
class student
{
protected:
char name[20];
int roll;
public:
void input( )
{
cout<<“Enter the name of an student:”<<endl;
cin>>name;
cout<<“Enter the roll number of an student:”<<endl;
cin>>roll;
}
void display( )
{
cout<<“The name of an student=“<<name<<endl;
cout<<“The roll number of an student=“<<roll<<endl;
}
};
class test:public student
{
protected:
float sub1,sub2;
public:
void input( )
{
student::input( );
cout<<“Enter the marks in subject1 and subject2:”<<endl;
cin>>sub1>>sub2; }
void display( )
{
student::display( );
cout<<“The marks of subject1=“<<sub1<<endl;
cout<<“The marks of subject2=“<<sub2<<endl;
}
};
class result: public test
{
protected:
float total;
public:
void input( )
{
test::input( );
total=sub1+sub2; }
void display( )
{
test::display( );
cout<<“Total=“<<total<<endl;
}
};
int main( )
{
result r;
r.input( );
r.display( );
return 0;
}
4)Hierarchical Inheritance:
The type of inheritance in which there is a single base class and multiple
derived classes is called hierarchical inheritance.
The general form is:
class base
{…………};
class derived1 : visibility_mode base
{ ….. }; For Example:
class derived2 : visibility_mode base class A
{ …. }; {…};
class derived3 : visibility_mode base class B : public A
{ …. };
{…};
.
class C : public A
.
{…};
class derived n:visibility_mode base
{ …. }; class D : public A
{…};
Example Program:
#include<iostream>
using namespace std;
class employee
{
protected:
char name[20];
float salary;
public:
void input( )
{
cout<<“Enter the name of an employee:”<<endl;
cin>>name;
cout<<“Enter the salary of an employee:”<<endl;
cin>>salary; }
void display( )
{
cout<<“Name of an employee=“<<name<<endl;
cout<<“Salary of an employee=“<<salary<<endl;
}
};
class manager: public employee
{
protected:
char title[20];
public:
void input( )
{
employee::input( );
cout<<“Enter the title of a manager:”<<endl;
cin>>title;
}
void display( )
{
employee::display( );
cout<<“The title of a manager=“<<title<<endl;
}
};
class teacher:public employee
{
protected:
char faculty[20];
public:
void input( )
{
employee::input( );
cout<<“Enter the faculty of the teacher:”<<endl;
cin>>faculty;
}
void display( )
{
employee::display( );
cout<<“The faculty of the teacher=“<<faculty;
}
};
int main( )
{
cout<<“Manager:”<<endl;
manager m;
m.input( );
cout<<“Teacher:”<<endl;
teacher t;
t.input( );
cout<<“Manager details:”<<endl;
m.display( );
cout<<“Teacher details:”<<endl;
t.display( );
return 0;
}
5)Hybrid Inheritance(Imp):
The type of inheritance in which there are more than
one inheritances mixed together.
General form (syntax):
class base1
{…………..};
class derived1:visibility_mode base1
{…………..};
class base2
{…………….}; Example:
class derived2:visibility_mode- class A{…};
derived1,visibility_mode base2 class B:public A
{…………….}; {…};
class C{…};
class D: public B, public C
{…};
#include<iostream>
using namespace std;
class student
{
protected:
char name[20];
int roll;
public:
void input( )
{
cout<<“Enter the name of the student:”<<endl;
cin>>name;
cout<<“Enter the roll number of the student:”<<endl;
cin>>roll;
}
void display( )
{
cout<<“Name of the student=“<<name<<endl;
cout<<“Roll number of the student=“<<roll<<endl;
}
};
class test: public student
{
protected:
float sub1,sub2;
public:
void input( )
{
student::input( );
cout<<“Enter the marks in subject1 and subject2:”<<endl;
cin>>sub1>>sub2;
}
void display( )
{
student::display( );
cout<<“The marks of subject1=“<<sub1<<endl;
cout<<“The marks of subject2=“<<sub2<<endl;
}
};
class sports
{
protected:
float sm;
public:
void input( )
{
cout<<“Enter the marks of sports:”<<endl;
cin>>sm;
}
void display( )
{
cout<<“The marks of the sports=“<<sm<<endl;
}
};
class result: public test, public sports
{
protected:
float total;
public:
void input( )
{
test::input( );
sports::input( );
total=sub1+sub2+sm;
}
void display( )
{
test::display( );
sports::display( );
cout<<“Total marks=“<<total<<endl;
}
};
int main( )
{
result r;
r.input( );
r.display( );
return 0;
}
6)Multipath Inheritance(Imp):
When two derived classes are formed from a single base class
and again these derived classes are combined as base to
another derived class then this type of inheritance is called
multipath inheritance.
Grandparent
Parent 1 Parent 2
Child
From above figure we see that the properties of grandparent is
inherited to parent1 and parent2 and again parent1 and parent2
are combined as base class to the derived class child. Due to
this the properties of grandparent will be the duplicate copies
to a derived class child via parent1 and parent2.
In order to solve this problem the concept of virtual base class
is used i.e. we make ancestor base class(grandparent class) as
virtual base class while deriving parent1 and parent2 by using
keyword virtual. Sometimes multipath inheritance is also
called as virtual inheritance.
After making ancestor class as virtual base class we can be
sure that only the single copy of the ancestor base class will be
inherited to the finally derived class child.
General syntax:
class base
{ …. };
class derived1:virtual visibility_mode base
{ …. }:
class derived2:virtual visibility_mode base
{ …. };
class derived: visibility_mode derived1,visibility_mode derived2
{ …. };
Example:
class Grandparent
{ …. };
class Parent1:virtual public Grandparent
{ …. }:
class Parent2:virtual public Grandparent
{ …. };
class Child: public Parent1,public Parent2
{ …. };
Example Program:
#include<iostream>
using namespace std;
class Base
{
protected:
int w;
public:
void get_w( )
{
cout<<“Enter the value to w of a Base class:”<<endl;
cin>>w;
}
void display_w( )
{
cout<<“The value to w of a Base class=“<<w<<endl;
}};
class derived1: virtual public Base
{
protected:
int x;
public:
void get_x( )
{
cout<<“Enter the value to the x of derived1:”<<endl;
cin>>x;
}
void display_x( )
{
cout<<“The value to the x of a derived1=“<<x<<endl;
}
};
class derived2:public virtual Base
{
protected:
int y;
public:
void get_y( )
{
cout<<“Enter the value to the y of a derived2:”<<endl;
cin>>y;
}
void display_y( )
{
cout<<“The value to the y of a derived2=“<<y<<endl;
}
};
class derived: public derived1,public derived2
{
protected:
int z;
public:
void get_z( )
{
cout<<“Enter the value to the z of a derived class:”<<endl;
cin>>z;
}
void display_z( )
{
cout<<“The value to the z of a derived class=“<<z<<endl;
}
void display( )
{
cout<<“The sum is:”<<w+x+y+z<<endl;//if no virtual keyword was used then
w should be written as derived1::w or derived2::w
}
};
int main( )
{
derived d;
d.get_w( );//if no virtual keyword was used then this statement will cause
error and it should be called as either d.derived1::get_w( ) or
d.derived2::get_w( );
d.get_x( );
d.get_y( );
d.get_z( );
d.display_w( );// if no virtual keyword was used then this statement will
cause error and it should be called as either d.derived1::display_w( ) or
d.derived2::display_w( );
d.display_x( );
d.display_y( );
d.display_z( );
d.display( );
return 0; }
OR Another example program
#include<iostream>
using namespace std;
class animal
{
public:
void display( )
{
cout<<"Animal class:"<<endl;
}
};
class cat: virtual public animal
{
public:
void display( )
{
cout<<"Cat class:"<<endl;
}
class dog: virtual public animal
{
public:
void display( )
{
cout<<"Dog class:"<<endl;
}
};
class domestic: public cat, public dog
{
public:
void display( )
{
animal::display( );//If no virtual base class concept is used then this
statment will generate an error message.
cat::display( );
dog::display( );
cout<<"Domestic class:"<<endl;
}
};
int main( )
{
domestic d;
d.display( );
return 0;
}
/*int main( )
{
domestic d;
d.animal::display( );//If no virtual base class concept is used then this
statement will generate an error message.
d.cat::display( );
d.dog::display( );
d.display( );
return 0;
}*/
Constructor in derived class:
If there is no constructor at all or there is a default constructor in a base class then it
is not necessary to have a constructor in a derived class. However if there is a
parameterized constructor in a base class then it is mandatory to have
parameterized constructor in a derived class too because it is the job of derived
class constructor to pass value(s) to the base class constructor.
Example program:
#include<iostream>
using namespace std;
class alpha
{
protected:
int x;
public:
alpha(int i)
{
x=i;
cout<<“alpha initialized”<<endl; }
void display_x( )
{
cout<<“x=“<<x<<endl;
}
};
class beta
{
protected:
int y;
public:
beta( int j)
{
y=j;
cout<<“beta initialized”<<endl;
}
void display_y( )
{
cout<<“y=“<<y<<endl;
}
};
class gamma: public alpha, public beta
{
protected:
int m,n;
public:
gamma(int a,int b,int c,int d):alpha(a),beta(b)
{
m=c;
n=d;
cout<<“gamma initialized”<<endl;
}
void display_mn( )
{
cout<<“m=“<<m<<endl;
cout<<“n=“<<n<<endl;
}
};
int main( )
{
gamma g(11,12,13,14);
g.display_x( );
g.display_y( );
g.display_mn( );
return 0;
}
Constructor and destructor invocation order in case of single
inheritance:(Imp)
If there are constructors in base class and derived class in single
inheritance then first the constructor of base class is invoked and
after that the constructor of derived class is invoked. The
destructors invocation order is the reverse order of invocation of
constructor.
#include<iostream>
using namespace std;
class Base
{
public:
Base( )
{
cout<<“Base class constructor:”<<endl;
}
~Base( )
{
cout<<“Base class destructor:”<<endl;
}
};
class Derived:public Base
{
public:
Derived( )
{
cout<<“Derived class constructor:”<<endl;
}
~Derived( )
{
cout<<“Derived class destructor:”<<endl;
}
};
int main( )
{
{
derived d;
}
cout<<“End of main:”<<endl;
return 0;
}
Output:
Base class constructor:
Derived class constructor:
Derived class destructor:
Base class destructor:
End of main:
Constructor and destructor invocation order in case of
multiple inheritance(Imp):
The constructors invocation in multiple inheritance take places
according to the order of the derived class declaration.
The destructors invocation order is reverse to the order of
invocation of the constructor.
#include<iostream>
using namespace std;
class Base1
{
public:
Base1( )
{
cout<<“Constructor from Base1:”<<endl;
}
~Base1( )
{
cout<<“Destructor from Base1:”<<endl;
}
};
class Base2
{
public:
Base2( )
{
cout<<“Constructor from Base2:”<<endl;
}
~Base2( )
{
cout<<“Destructor from Base2:”<<endl;
}
};
class Derived:public Base1,public Base2
{
public:
Derived( )
{
cout<<“Constructor from Derived:”<<endl;
}
~Derived( )
{
cout<<“Destructor from Derived:”<<endl;
}
};
int main( )
{
{
Derived d;
}
cout<<“End of main:”<<endl;
return 0;
}
Output:
Constructor from Base1:
Constructor from Base2:
Constructor from Derived:
Destructor from Derived:
Destructor form Base2:
Destructor from Base1:
End of main:
Constructor and destructor invocation order in case of
multilevel inheritance:(Imp)
The order of constructors invocation takes place in case of
multilevel inheritance according to the order of inheritance.
Destructors invocation takes place according to the reverse order of
the invocation of the constructor.
Example program:
#include<iostream>
using namespace std;
class Base
{
public:
Base( )
{
cout<<“Base class constructor:”<<endl;
}
~Base( )
{
cout<<“Base class destructor:”<<endl;
}
};
class derived1:public Base
{
public:
derived1( )
{
cout<<“derived1 class constructor:”<<endl;
}
~derived1( )
{
cout<<“derived1 class destructor:”<<endl;
}
};
class derived2:public derived1
{
public:
derived2( )
{
cout<<“derived2 class constructor:”<<endl;
}
~derived2( )
{
cout<<“derived2 class destructor:”<<endl;
}
};
int main( )
{
{
derived2 d;
}
cout<<“End of main:”<<endl;
return 0;
}
Output:
Base class constructor:
derived1 class constructor:
derived2 class constructor:
derived2 class destructor:
derived1 class destructor:
Base class destructor:
End of main: