Download as pdf or txt
Download as pdf or txt
You are on page 1of 30

Inheritance

In C++
Introduction
• Reusability: one of the important features of OOPs. We can reuse a class
that has already been tested, debugged and used many times can save us the
effort of developing and testing the same again.
• It means that creating new classes, reusing the properties of the existing
classes. This is called INHERITANCE. The old class is called Base Class
and new Class is called Derived Class.
• The derived class can inherit all or some of the properties of the base class.
It can also be done from multiple or multilevel classes. Depending on it we
have different types of Inheritance.
Types of Inheritance;
1. Single Inheritance
2. Multiple Inheritance
3. Hierarchical Inheritance
4. Multilevel Inheritance
5. Hybrid Inheritance
Types of Inheritance

Single Inheritance Multiple Inheritance

Hierarchical Inheritance

Multilevel Inheritance

Hybrid (Virtual) Inheritance


Defining Derived Classes
• The derived class can be defined by specifying its relationship with the
base class in addition to its own details:
class derived-class-name: visibility-mode base-class-name
{
::::::::::::::
};
Visibility mode is optional, if not present is Private by default.
• Private Mode: In this mode, the public members of the base class becomes
private members of the derived class, hence they are accessible to the
functions of the derived class, but they are not accessible to the objects of
the derived class, and also cannot be further inherited.
• Public Mode: In this mode, the public members of the base class becomes
public members of the derived class, hence they are accessible to the
functions and the objects of the derived class.
• In both the cases the private members are not inherited.
• Apart from adding the data and functions of the Base Class the derived
class can have its own data and functions also.
Example
#include <iostream> class derived : public base {
using namespace std; int k;
public:
derived(int x) {
class base {
k=x;
int i, j; }
public: void showk()
void set(int a, int b) {
{ cout << k << "\n";
i=a; j=b; }
};
}
int main()
void show() {
{ derived ob(3);
ob.set(1, 2); // access member of base
cout << i << " " << j << ob.show(); // access member of base
"\n"; ob.showk(); // uses member of
} derived class
}; return 0;
}
#include <iostream>
using namespace std;
class base {
int i, j;
public:
void set(int a, int b) { i=a; j=b; }
void show() { cout << i << " " << j << "\n";}
};

// Public elements of base are private in derived.


class derived : private base {
int k;
public:
derived(int x) { k=x; }
void showk() { cout << k << "\n"; }
};

int main()
{
derived ob(3);
ob.set(1, 2); // ??
ob.show(); //??
return 0;
}
Protected Access Specifier
• The protected keyword is included in C++ to provide greater flexibility.
• When a member of a class is declared as protected, that member is not accessible
by other, non-member elements of the program.
• Similar to private member with one exception.
• If the base class is inherited as public, then the base class' protected members
become protected members of the derived class and are, therefore, accessible by the
derived class.
• By using protected, you can create class members that are private to their class but
that can still be inherited and accessed by a derived class.
Example
#include <iostream>
public:
using namespace std; // derived may access base's i and j
class base { void setk()
ember {
protected: k=i*j;
int i, j; // private to base, but accessible }
by derived void showk()
{
public:
cout << k << "\n";
void set(int a, int b) }
{ };
i=a; j=b; int main()
} {
void show() derived ob;
ob.set(2, 3); // OK, known to derived
{
ob.show(); // OK, known to derived
cout << i << " " << j << "\n"; ob.setk();
} ob.showk();
}; return 0;
class derived : public base { }
int k;
Single Inheritance
• Here a single class is inherited to another class. We can have the inheritance in
Public Mode or Private Mode.
• Inheritance in Public Mode: Here as the inheritance is in public mode the public
members of the base class becomes the public members of the Derived class,
hence they can be accessed by the functions and objects of the derived class.

• Inheritance in Private Mode: Here as the inheritance is in private mode the


public members of the base class becomes the private members of the Derived
class, hence the public member functions of the base class can not be directly
accessed by the objects of the derived class, however the public member functions
of the base class can be accessed indirectly through the member functions of the
derived class.
Single Inheritance in Protected Mode
• We can make the private member of the Base Class inheritable to the derived class
by just using the protected section. The data members of the protected section are
otherwise private in the base class but they are inheritable in the derived class.

• The visibility modifier Protected serves a limited purpose in inheritance. The


members declared in the protected section is accessible by the member functions
within its class and any class immediately derived form it. It cannot be accessed by
the functions outside these two classes.

• Public Mode: When a protected member is inherited in public mode, it becomes


protected in the derived class too. i.e. it is ready for further inheritance.

• Private Mode: When a protected member is inherited in private mode, it becomes


private in the derived class too. Also the public members of the base class become
private in the derived class. i.e. it is not ready for further inheritance.

• Protected Mode: Class can also be inherited in protected mode, both the public and
protected members of the base class become protected members of the derived
class.

• The keywords private, public, protected may appear any no. of time in the class
declaration.
Single Inheritance
• Access Control to the Private and Protected members of a class, what are the
various functions that can have access to these members?

1. A function that is a friend of the class.


2. A member function of class that is a friend of the class.
3. A member function of a derived class.

Base Class Visibility Derived Class Visibility

Public Derivation Private Derivation Protected Derivation

Private Not Inherited Not Inherited Not Inherited

Protected Protected Private Protected

Public Public Private Protected


Protected Base-Class Inheritance
// Inherit base as protected.
#include <iostream>
class derived : protected base{
using namespace std; int k;
class base public:
{ // derived may access base's i and j and setij().
protected: void setk() {
int i, j; // private to base, but setij(10, 12); k = i*j;
//accessible by derived }
// may access showij() here
public:
void showall() {
void setij(int a, int b) cout << k << " "; showij();
{ }
i=a; };
j=b; int main()
} {
derived ob;
void showij()
// ob.setij(2, 3); // illegal, setij() is
{ // protected member of derived
cout << i << " " << j << "\n"; ob.setk(); // OK, public member of derived
} ob.showall(); // OK, public member of derived
}; // ob.showij(); // illegal, showij() is protected
// member of derived
return 0;
}
Multiple Inheritance
• A class can inherit the attributes of two or more classes.

// An example of multiple base classes.


#include <iostream> // Inherit multiple base classes.
using namespace std; class derived: public base1, public base2 {
public:
class base1 {
void set(int i, int j) { x=i; y=j; }
protected: };
int x; int main()
public: {
void showx() { cout << x << "\n"; } derived ob;
}; ob.set(10, 20); // provided by derived
ob.showx(); // from base1
class base2 {
ob.showy(); // from base2
protected: return 0;
int y; }
public:
void showy() { cout << y << "\n";}
};
Multilevel Inheritance
When a class B is derived from A and then in turn Class B can serve as the base class
for derived class C. Class B is called Intermediate Class.
// i and j inherited indirectly through derived1.
#include <iostream> class derived2 : public derived1 {
using namespace std; int m;
public:
class base { void setm() { m = i-j; } // legal
protected: void showm() { cout << m << "\n";}
int i, j; };
public: int main()
void set(int a, int b) { i=a; j=b; } {
void show() { cout << i << " " << j << "\n"; } derived1 ob1;
}; derived2 ob2;
ob1.set(2, 3);
// i and j inherited as protected. ob1.show();
class derived1 : public base { ob1.setk();
int k; ob1.showk();
public: ob2.set(3, 4);
void setk() { k = i*j; } // legal ob2.show();
void showk() { cout << k << "\n"; } ob2.setk();
}; ob2.setm();
ob2.showk();
ob2.showm();
return 0;
}
#include <iostream> class derived2 : public derived1 {
using namespace std; int m;
public:
class base {
void setm() { m = i-j; } //Valid or
protected: invalid
int i, j; void showm()
public: {
void set(int a, int b) { i=a; j=b; } cout << m << "\n";
void show() { cout << i << " " << j << "\n"; } }
};
};
int main()
{
class derived1 : private base { derived1 ob1;
int k; derived2 ob2;
public: ob1.set(1, 2); // Valid or Invalid
void setk() { k = i*j; } // Valid or invalid ob1.show(); // Valid or Invalid
ob2.set(3, 4); // Valid or Invalid
void showk() { cout << k << "\n"; }
ob2.show(); // Valid or Invalid
}; return 0;
}
Hierarchical Inheritance
Till now we have seen that we can extend the capabilities of the existing class
by adding some more data and functions to it. Inheritance can also be used for
the hierarchical design of the Program. E.g.

Students

Arts Engineering Medical

Mechanical Electrical Civil

• Here we have a hierarchical classification of the Students in a University.


Example
// C++ program to demonstrate hierarchical // derived class 2
inheritance class Cat : public Animal {
public:
#include <iostream> void meow() {
using namespace std; cout << "I am a Cat. Meow." << endl;
}
};
// base class
class Animal { int main() {
public: // Create object of Dog class
void info() { Dog dog1;
cout << "I am an animal." << endl; cout << "Dog Class:" << endl;
} dog1.info(); // Parent Class function
dog1.bark();
};
// Create object of Cat class
// derived class 1 Cat cat1;
class Dog : public Animal { cout << "\nCat Class:" << endl;
public: cat1.info(); // Parent Class function
void bark() { cat1.meow();
cout << "I am a Dog. Woof woof." << endl;
return 0;
} }
};
Hybrid Inheritance
The inheritance in which the derivation of a class involves more than one form of any
inheritance is called hybrid inheritance.

class A
{
.........
};
class B : public A
{
..........
};
class C
{
...........
};
class D : public B, public C
{
...........
};
Ambiguity Resolution in Inheritance
• Sometimes we face the problem in using the Multiple Inheritance, when a function
with the same name appears in more than one base classes. E.g.
class M
{
void display(void)
{
cout<<“Class M\n”;
}
};
class N
{
void display(void)
{
cout<<“Class N\n”;
}
};
Which of the display function is used by the derived class, when we inherit these two
classes.
Ambiguity Resolution in Inheritance
• We can solve this problem by defining a named instance within the derived class, using
the class Resolution Operator with the function:

class P: public M, public N


{
public:
void display(void) // Overrides display() of M and N.
{
M:: display();
}
};

• Ambiguity may also arise in Single Inheritance also:

class A class B: public A


{ {
public: public:
void display() void display()
{ {
cout<<“A\n”; cout<<“B\n”;
} }
}; };
Ambiguity Resolution in Inheritance
Here in this case when we invoke display function through an object of class B type,
the display function of class B is invoked, however we can invoke the display function
of class A by using Scope Resolution Operator.
int main()
{
B b;
b.display(); // Invokes Display Function in B
b.A::display(); // Invokes Display Function in A
b.B::display(); // Invokes Display Function in B
return();
}
Output:
B
A
B
Constructors, Destructors and Inheritance
Two things need to be addressed related to constructors and destructors when
inheritance is involved
•When are base-class and derived-class constructor and destructor functions called?
•Second, how can parameters be passed to base-class constructor functions?

When Constructor and Destructor Functions Are Executed

#include <iostream> int main()


using namespace std; {
class base { derived ob;
public: // do nothing but construct and destruct ob
base() { cout << "Constructing base\n"; } return 0;
~base() { cout << "Destructing base\n"; } }
};
class derived: public base { Output:
public: Constructing base
derived() { cout << "Constructing derived\n"; } Constructing derived
~derived() { cout << "Destructing derived\n"; } Destructing derived
}; Destructing base
When Constructor and Destructor Functions Are Executed

•When an object of a derived class is created, if the base class contains a constructor, it
will be called first, followed by the derived class' constructor.
•When a derived object is destroyed, its destructor is called first, followed by the base
class' destructor, if it exists.

Note: Constructor functions are executed in their order of derivation. Destructor


functions are executed in reverse order of derivation

The above rule applies to multiple and multi-level inheritance also.

•Constructors are called in order of derivation, left to right, as specified in derived's inheritance
list. Destructors are called in reverse order, right to left.
Multilevel Inheritance Multiple Inheritance
#include <iostream>
#include <iostream>
using namespace std;
using namespace std;
class base { class base1 {
public: public:
base() { cout << "Constructing base\n"; } base1() { cout << "Constructing base1\n"; }
~base() { cout << "Destructing base\n"; } ~base1() { cout << "Destructing base1\n"; }
}; };
class base2 {
class derived1 : public base {
public:
public: base2() { cout << "Constructing base2\n"; }
derived1() { cout << "Constructing derived1\n"; } ~base2() { cout << "Destructing base2\n"; }
~derived1() { cout << "Destructing derived1\n"; } };
}; class derived: public base1, public base2 {
class derived2: public derived1 { public:
derived() { cout << "Constructing derived\n"; }
public:
~derived() { cout << "Destructing derived\n"; }
derived2() { cout << "Constructing derived2\n"; } };
~derived2() { cout << "Destructing derived2\n"; }
}; int main()
{
int main() derived ob;
// construct and destruct ob
{
return 0;
derived2 ob; }
// construct and destruct ob
return 0;
}
Passing Parameters to Base-Class Constructors
• If base class constructor does not takes any argument, the derived class need not have a
constructor function.
• However, if any base class contains a constructor with one or more arguments , then it
becomes mandatory for the derived class to have a constructor and pass the arguments to the
base class constructor.

General Form of derived class constructor declaration:

derived-constructor(arg-list) : base1(arg-list),
base2(arg-list),
// ...
baseN(arg-list)
{
// body of derived constructor
}
#include <iostream>
using namespace std;
class base {
protected:
int i;
public:
base(int x) { i=x; cout << "Constructing base\n"; }
~base() { cout << "Destructing base\n"; }
};
class derived: public base {
int j;
public:
// derived uses x; y is passed along to base.
derived(int x, int y): base(y)
{
j=x;
cout << "Constructing derived\n";
}
~derived() { cout << "Destructing derived\n"; }
void show() { cout << i << " " << j << "\n"; }
};
int main()
{
derived ob(3, 4);
ob.show(); // displays 4 3
return 0;}
Passing arguments to base class constructor in case of
Multiple Base classes
#include <iostream>
using namespace std; class derived: public base1, public base2 {
int j;
class base1 {
public:
protected:
int i; derived(int x, int y, int z): base1(y), base2(z)
public: {
base1(int x) j=x;
{ cout << "Constructing derived\n";
}
i=x;
~derived() {
cout << "Constructing base1\n"; } cout << "Destructing derived\n";
~base1() { cout << "Destructing base1\n"; } }
};
class base2 { void show() {
protected: cout << i << " " << j << " " << k << "\n";
}
int k;
};
public:
base2(int x) int main()
{ {
k=x; derived ob(3, 4, 5);
cout << "Constructing base2\n"; } ob.show();
return 0;
~base2() { cout << "Destructing base1\n"; }
}
};
A derived class' constructor function is free to make use of any and all
parameters that it is declared as taking, even if one or more are passed along to
a base class.

class derived: public base {


int j;
public:
// derived uses both x and y and then passes them to base.
derived(int x, int y): base(x, y)
{
j = x*y;
cout << "Constructing derived\n";
}
Virtual Base Classes
• An element of ambiguity can be introduced into a C++ program when multiple base
classes are inherited.

#include <iostream> /* derived3 inherits both derived1 and derived2.


using namespace std; This means that there are two copies of base
class base { in derived3! */
class derived3 : public derived1, public derived2 {
public:
public:
int i; int sum;
}; };
// derived1 inherits base.
class derived1 : public base { int main()
public: {
ember
int j;
derived3 ob;
}; ob.i = 10; // this is ambiguous, which i???
// derived2 inherits base. ob.j = 20;
class derived2 : public base { ob.k = 30;
public: b.derived1::i
int k; // i ambiguous here, too
ob.sum = ob.i + ob.j + ob.k;
};
// also ambiguous, which i?
cout << ob.i << " ";
cout << ob.j << " " << ob.k << " ";
cout << ob.sum;
return 0;
}
• When two or more objects are derived from a common base class, you can prevent
multiple copies of the base class from being present in an object derived from those
objects by declaring the base class as virtual when it is inherited
// This program uses virtual base classes.
#include <iostream>
using namespace std; int main()
class base { {
public: derived3 ob;
int i; ob.i = 10; // now unambiguous
}; ob.j = 20;
// derived1 inherits base as virtual. ob.k = 30;
class derived1 : virtual public base { // unambiguous
public: ob.sum = ob.i + ob.j + ob.k;
int j; // unambiguous
}; cout << ob.i << " ";
// derived2 inherits base as virtual. cout << ob.j << " " << ob.k << " ";
class derived2 : virtual public base { cout << ob.sum;
public: return 0;
int k; }
};
/* derived3 inherits both derived1 and derived2.
This time, there is only one copy of base class. */
class derived3 : public derived1, public derived2 {
public:
int sum;
};

You might also like