C++ Inheritance
C++ Inheritance
C++ Inheritance
⦿ The old class is called ‘BASE’ class and the new one
is called ‘DERIVED’ class or sub-class.
C++
Inheritance
General Format for implementing the concept of Inheritance:
Class C Derived
class
How does multiple inheritance differ from multilevel inheritance?
Though multiple and multilevel sounds like same but they differ
hugely in meaning.
For example
Multilevel inheritance : Inheritance of characters by a child from
father and father inheriting characters from his father (grandfather)
Syntax:
Class B Class C
Class D
class sports{
protected:
#include <iostream> int spmarks;
#include <string> public:
using namespace std; void getsports(){
//Hybrid inheritance = multilevel + multilpe cout << "Enter sports marks:";
class student{ //First base Class cin >> spmarks;
int id; }};
string name; class result : public marks, public sports{
public: int total_marks;
void getstudent(){ float avg_marks;
cout << "Enter student Id and student name"; public :
cin >> id >> name; void display(){
} total_marks=math+phy+chem;
}; avg_marks=total_marks/3.0;
class marks: public student{ cout << "Total marks =" << total_marks
protected: << endl;
int math, phy, chem; cout << "Average marks =" << avg_marks
public: << endl;
void getmarks(){ cout << "Average + Sports marks =" <<
cout << "Enter 3 subject marks:"; avg_marks+spmarks;
cin >>math>>phy>>chem; } };
} }; int main(){
result res; res.getstudent(); res.getmarks();
res.getsports(); res.display();
return 0;}
int B::get_a(void) {
Examples: }
return a;
class B {
int a; • In private derivation, the public members of the base
public: class become private members of the derived class.
int b;
void get_ab(); • Therefore, the objects of D cannot have direct access
int get_a(); to the public member functions of B.
void show_a();
}; • The statements such as:
• d.get_ab();
class D : private B { • d.get_a();
int c; • d.show_a();
public:
void mul(); • will not work because they become private in the
void display(); derived class, but they can be accessed inside the
}; class functions like mul() and display().
void D::mul(void) int main() {
{ D d;
get_ab(); d.get_ab(); //
c = b* get_a();
d.mul();
}
d.show_a(); //
void D::display(void)
{ d.display();
show_a(); d.b = 20; //
cout << "b = " << b << "\n"; d.mul(); d.display();
cout << "c = " << c << "\n"; return 0;
} }
Case of Protected Derivation:
int main() {
class Dog : protected Dog d;
Animal { d.setDogAge(5);
class Animal { d.displayDogAge(); //
public:
protected: Will display dog's age
void setDogAge(int
int age; (accessing base class's
a) {
setAge(a); // age)
public:
Accessing protected
void setAge(int a) { // d.setAge(10); // This
member function of
age = a; will cause a compile-time
base class
} error
}
// d.displayAge(); //
void displayAge() { This will cause a
void
cout << "Animal's compile-time error
displayDogAge() {
Age: " << age << endl;
displayAge(); //
} return 0;
Accessing protected
}; }
member function of
base class
}
};
Order of Constructor/ Destructor Call
in C++
⦿ Whenever we create an object of a class, the
default constructor of that class is invoked
automatically to initialize the members of the
class.
#include <iostream>
using namespace std;
class Parent Output:
{ public: Inside base class
Parent() Inside sub class
{
cout << "Inside base class" << endl;
} };
class Child : public Parent
{
public:
//sub class constructor
Child()
{cout << "Inside sub class" << endl;
}};
int main() {
Child obj;
return 0;
}
// C++ program to show the order of constructor calls
// in Multiple Inheritance
// sub class
#include <iostream>
class Child : public Parent
using namespace std;
{
// base class
public:
class Parent
// sub class's parameterised constructor
{
Child(int j): Parent(j)
public:
{
// base class's parameterised
cout << "Inside sub class's parameterised
constructor
constructor" << endl;
Parent(int i)
}};
{ int x =i;
int main() {
cout << "Inside base class's
// creating object of class Child
parameterised constructor" << endl;
Child obj1(10);
}
return 0;
};
}
class gamma : public
Example: beta, public alpha
{
int m, n;
public:
class alpha class beta int main() {
gamma(int a, float b,
{ { int c, int d) : alpha(a), gamma g(5,
int x; float y; beta(b) 10.75, 20, 30);
public: public: {
alpha(int i) beta(float j) cout << "\n";
m = c;
{ { n = d; g.show_x();
x = i; y = j; cout << "gamma
cout << "alpha cout << "beta g.show_y();
initialized \n";
initialized \n"; initialized \n"; } g.show_mn();
} } void show_mn(void)
void show_x(void) void {
{ show_y(void) return 0;
cout << "m = " << m
cout << "x = " << { << "\n"; }
x << "\n"; cout << "y = " cout << "n = " << n <<
} << y << "\n"; "\n";
}; } }
}; };
Important Points:
class B:public A {
public:
void display() {
cout<<"Derived Class";
}
};
int main() {
B obj;
obj.display();
return 0;
}
Access Overridden Function in C++
class Base {
public:
void print() {
cout << "Base Function" << endl;
}};
class Derived : public Base {
public:
void print() {
cout << "Derived Function" << endl;
// call overridden function
Base::print();
}};
int main() {
Derived derived1;
derived1.print();
return 0;
}
A special case of hybrid inheritance : Multipath
inheritance
⦿ A derived class with two base classes and these two base
classes have one common base class is called multipath
inheritance. An ambiguity can arise in this type of
inheritance.
C++ program demonstrating ambiguity in Multipath
Inheritance
void main()
#include<iostream.h>
{ ClassD obj;
#include<conio.h>
//obj.a = 10; //Statement 1, Error
class ClassA
//obj.a = 100; //Statement 2, Error
{ public:
obj.ClassB::a = 10; //Statement 3
int a; };
obj.ClassC::a = 100; //Statement 4
class ClassB : public ClassA
obj.b = 20; obj.c = 30;
{ public:
obj.d = 40;
int b; };
cout<< "\n A from ClassB : "<<
class ClassC : public ClassA
obj.ClassB::a;
{ public:
cout<< "\n A from ClassC : "<<
int c; };
obj.ClassC::a;
class ClassD : public ClassB, ClassC
cout<< "\n B : "<< obj.b;
{ public:
cout<< "\n C : "<< obj.c;
int d;};
cout<< "\n D : "<< obj.d;
}
⦿ In the example, both ClassB & ClassC inherit ClassA, they
both have single copy of ClassA.
#include <iostream>
using namespace std; Compile Errors:
class A { prog.cpp: In function 'int main()':
public: prog.cpp:29:9: error: request for member
void show() 'show' is ambiguous
{ object.show();
cout << "Hello form A \n"; ^
}}; prog.cpp:8:8: note: candidates are: void
class B : public A { }; A::show()
class C : public A { }; void show()
class D : public B, public C { }; ^
int main() prog.cpp:8:8: note: void A::show()
{
D object;
object.show();
}
⦿ To resolve this ambiguity when class A is inherited in
both class B and class C, it is declared as virtual base
class by placing a keyword virtual as :
⦿ A single copy of its data members is shared by all the base classes that use
virtual base.
class A {
public:
void show()
{
cout << "Hello from A \n";
}};
class B : public virtual A { };
class C : public virtual A { };
class D : public B, public C { };
int main()
{
D object;
object.show();
}
class ClassA
{ public:
int a; };
class ClassB : virtual public ClassA
{ public:
int b; }; Output:
class ClassC : virtual public ClassA A : 100
{ public: B : 20
int c; }; C : 30
class ClassD : public ClassB, public ClassC D : 40
{ public:
int d; };
void main() ClassD has only one copy of ClassA,
{ ClassD obj; therefore, statement 4 will overwrite the
obj.a = 10; //Statement 3 value of a, given at statement 3
obj.a = 100; //Statement 4
obj.b = 20; obj.c = 30; obj.d = 40;
cout<< "\n A : "<< obj.a;
cout<< "\n B : "<< obj.b;
cout<< "\n C : "<< obj.c;
cout<< "\n D : "<< obj.d;
}
⦿ The problem of duplicate sub-objects is resolved with virtual inheritance. When a
base class is inherited as virtual, only one sub-object will appear in the derived
class—a process called virtual base-class inheritance.
# include <iostream.h> class A2 : Virtual public A
# include< conio.h> { protected:
Class A int z;
{ protected: public:
int x; void get (int a)
public: { z = a;}
void get (int); void show (void)
void show (void);}; { cout << z;}};
void A :: get (int a) class A12 : public A1, public A2
{ x = a; } {int r, t;
void A :: show (void) public:
{ cout << X;} void get (int a)
Class A1 : Virtual Public A { r = a;}
{ protected: void show (void)
int y; { t = x + y + z + r;
public: cout << “result =”<< t;}};
void get (int); Int main ( )
void show (void);}; { A12 r;
void A1 :: get (int a) r.A : : get (3); r.A1: : get (4);
{ y = a;} r.A2 : : get (5); r.get (6);
void A1 :: show (void) r.show();}
{ cout <<y;}
The constructors for virtual base classes are invoked before any non-virtual base
classes. If there are multiple virtual base classes, they are invoked in the order in
which they are declared. Any non-virtual bases are then constructed before the
derived class constructor is executed.
Class Hierarchies
For scientists, it stores the number of scholarly articles they have published.
Laborers need no additional data beyond their names and numbers.
⦿ Our example program starts with a base class employee. This class handles
the employee’s last name and employee number. From this class three other
classes are derived: manager, scientist, and laborer.
// Container class
class second {
// Container class
class second {
// creating object of first
first f;
public:
// constructor
second()
{
// calling function of first class
f.showf();
}
};
Example 2:
int main()
class first { {
public: // creating object of second
first() second s;
{ }
cout << "Hello from
first class\n";
}
};
Output:
// Container class Hello from first class
class second { Hello from second class
// creating object of first
first f;
public:
// constructor *when default constructor of class second is
second() called, due to presence of object f of first class
{ in second, default constructor of class first is
cout << "Hello from called first and then default constructor of
second class\n"; class second is called .
}
};
⦿ With the help of containership we can only use public member/function of
the class but not protected or private.
cEmployee :: cEmployee(int i, int sal,
int d, int m, int y)
class cDate
// Container class { mId = i;
{
class cEmployee mBasicSal = sal;
int
{ mBdate = cDate(d,m,y); }
mDay,mMonth,mYear;
protected: void cEmployee::display()
public:
int mId; {
cDate()
int mBasicSal; cout << "Id : " << mId << endl;
{ mDay = 10;
// Contained Object cout << "Salary :" <<mBasicSal <<
mMonth = 11;
cDate mBdate; endl;
mYear = 1999; }
public: mBdate.display();
cDate(int d,int m ,int y)
cEmployee() }
{ mDay = d;
{ int main()
mMonth = m;
mId = 1; {
mYear = y; }
mBasicSal = 10000; // Default constructor call
void display()
mBdate = cDate(); cEmployee e1;
{
} e1.display();
cout << "day" <<
cEmployee(int, int, int, // Parameterized constructor called
mDay << endl;
int, int); cEmployee
cout <<"Month" <<
void display(); e2(2,20000,11,11,1999);
mMonth << endl;
}; e2.display();
cout << "Year" <<
return 0;
mYear << endl;
}
} };
Output:
Id : 1
Salary :10000
day 10
Month 11
Year 1999
Id : 2
Salary :20000
day 11
Month 11
Year 1999
Nested Classes in C++
⦿ A nested class is a class that is declared in another
class. The nested class is also a member variable of
the enclosing class and has the same access rights as
the other members.
⦿ However, the member functions of the enclosing class
have no special access to the members of a nested
class.
Example
class A {
public: int main() {
class B { cout<<"Nested classes in C++"<<
private: endl;
int num; A :: B obj;
public: obj.getdata(9);
void getdata(int n) { obj.putdata();
num = n; return 0;
} }
void putdata() {
cout<<"The number is "<<num;
}
};
};
Aggregation in UML
⦿ In C++, aggregation and composition are two types of
relationships that represent how objects of different classes are
connected to each other.
Manager and scientist classes are derived from the employee and student
classes using the inheritance relationship.
Here, manager and scientist classes contain instances of the employee and
student classes as attributes
The following miniprogram shows these relationships in a
different way:
class student
{};
class employee
{};
class manager
{
student stu; // stu is an object of class student
employee emp; // emp is an object of class employee
};
class scientist
{
student stu; // stu is an object of class student
employee emp; // emp is an object of class employee
};
class laborer
{
employee emp; // emp is an object of class employee
};
Program:
Student stu1;
Employee emp1, emp2;
Laborer lab(emp1);
lab.labor(); // Laborer does the work
return 0;
}
Composition: A Stronger Aggregation
A car is composed of doors (among other things). The doors can’t belong to
some other car, and they are born and die along with the car.
void performOperationsSimple(){
cout<<"The value of a + b is: "<<a + b<<endl;
cout<<"The value of a - b is: "<<a - b<<endl;
cout<<"The value of a * b is: "<<a * b<<endl;
cout<<"The value of a / b is: "<<a / b<<endl;
}
};
class ScientificCalculator{
int a, b;
public:
void getDataScientific()
{
cout << "Enter the value of a" << endl;
cin >> a;
cout << "Enter the value of b" << endl;
cin >> b;
}
void performOperationsScientific()
{
cout << "The value of cos(a) is: " << cos(a) << endl;
cout << "The value of sin(a) is: " << sin(a) << endl;
cout << "The value of exp(a) is: " << exp(a) << endl;
cout << "The value of tan(a) is: " << tan(a) << endl;
}
};
class HybridCalculator : public SimpleCalculator, public ScientificCalculator
{
};
1. What type of Inheritance are you using?
int main() 2. Which mode of Inheritance are you using?
{
HybridCalculator calc;
calc.getDataScientific();
calc.performOperationsScientific();
calc.getDataSimple();
calc.performOperationsSimple();
return 0;
}
Polymorphism
⦿ Polymorphism is a feature of OOPS that allows
the object to behave differently in different
conditions. In C++ we have two types of
polymorphism:
⦿ 1) Compile time Polymorphism
⦿ 2) Runtime Polymorphism
Compile time Polymorphism
⦿ In compile-time polymorphism, a function is
called at the time of program compilation.
⦿ We call this type of polymorphism as early
binding or Static binding.