0% found this document useful (0 votes)
29 views85 pages

C++ Inheritance

C++ inheritance allows the creation of derived classes from base classes, enabling code reusability and reducing redundancy. It can take various forms, including single, multilevel, multiple, hierarchical, and hybrid inheritance, each with specific characteristics and use cases. Access specifiers (public, private, protected) determine the visibility of inherited members, and constructors are called in a specific order when creating objects of derived classes.

Uploaded by

shravani.mule
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views85 pages

C++ Inheritance

C++ inheritance allows the creation of derived classes from base classes, enabling code reusability and reducing redundancy. It can take various forms, including single, multilevel, multiple, hierarchical, and hybrid inheritance, each with specific characteristics and use cases. Access specifiers (public, private, protected) determine the visibility of inherited members, and constructors are called in a specific order when creating objects of derived classes.

Uploaded by

shravani.mule
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 85

C++ Inheritance

C++ Inheritance

One of the most important concepts in object-oriented.


Inheritance is the process of creating new classes, called
derived classes, from existing or base classes.

The derived class inherits all the capabilities of the base


class but can add embellishments and refinements of its
own. The base class is unchanged by this process.

Inheritance is an essential part of OOP. Its big payoff is


that it permits code reusability. Once a base class is
written and debugged, it need not be touched again, but,
using inheritance, can nevertheless be adapted to work in
different situations.
⦿ Why and when to use inheritance:

⦿ Consider a group of vehicles. You need to create classes for


Bus, Car and Truck. The methods fuelAmount(), capacity(),
applyBrakes() will be same for all of the three classes. If we
create these classes avoiding inheritance then we have to write
all of these functions in each of the three classes.

⦿ You can clearly see that above process results in duplication of


same code 3 times. This increases the chances of error and data
redundancy.

⦿ To avoid this type of situation, inheritance is used. If we create


a class Vehicle and write these three functions in it and inherit
the rest of the classes from the vehicle class, then we can
simply avoid the duplication of data and increase re-usability.
Derived Class and Base Class
⦿ The mechanism of deriving a new class from an old
one is called ‘INHERITANCE’.

⦿ This is often referred to as ‘IS-A’ relationship because


every object of the class being defined “is” also an
object of inherited class type.

⦿ 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 derived_classname: access specifier


baseclassname
For example, if the base class is MyClass and the derived
class is sample it is specified as:

class sample: public MyClass

The above makes sample have access to both public and


protected variables of base class MyClass
⦿ The colon (:) indicates that the derived classname class is
derived from the baseclass name class.

⦿ The access_specifier or the visibility mode is optional and, if


present, may be public, private or protected.

⦿ By default it is private. Visibility mode describes the


accessibility status of derived features.
C++
Inheritance
public, private and protected access specifiers:

1 If a member or variables defined in a class is private, then


they are accessible by members of the same class only and
cannot be accessed from outside the class.

2 Public members and variables are accessible from outside


the class.

3 Protected access specifier is a stage between private and


public. If a member functions or variables defined in a class
are protected, then they cannot be accessed from outside
the class but can be accessed from the derived class.
Note: A derived class doesn’t inherit access to private data members. However, it
does inherit a full parent object, which contains any private members which that
class declares.

1. class ABC : private XYZ //private derivation


{ }
2. class ABC : public XYZ //public derivation
{ }
3. class ABC : protected XYZ //protected derivation
{ }
4. class ABC: XYZ //private derivation by default
{ }
⦿ Modes of Inheritance-
⦿ 1. Public mode: If we derive a derived class from a public base
class. Then the public member of the base class will become
public in the derived class and protected members of the base
class will become protected in derived class.

⦿ 2. Protected mode: If we derive a derived class from a


Protected base class. Then both public member and protected
members of the base class will become protected in derived
class.

⦿ 3. Private mode: If we derive a derived class from a Private


base class. Then both public member and protected members
of the base class will become Private in derived class.
Types of
Inheritance
1. Single class Inheritance:

Single inheritance is the one where you have a


single base class and a single derived class.

Class Employee It is a Base class (super)

Class Manager it is a sub class


(derived)
Single Inheritance Example
#include<iostream>
using namespace std;
class A { void putdata()
protected: {
int x; cout<<“Addition :"<< x + y<< endl;
public: }};
void input()
{ int main ( )
cout<<"Enter a number:"<<endl;
cin>>x; { B b1;
}}; b1.input ( );
Class B: Public A b1.getdata ( );
{ b1.putdata ( );
int y; return 0;
public:
void getdata ( ) { }
cout << “Enter Number: " << y
<< endl;
cin>>y; }
Types of Inheritance
2. Multilevel Inheritance:

In Multi level inheritance, a class inherits its properties from


another derived class. If a class is derived from another derived
class then it is called multilevel inheritance. So in C++ multilevel
inheritance, a class has more than one parent class.

Class A it is a Base class (super) of B

Class B it is a sub class (derived)


of A
and base class of class
C
Class C derived class(sub) of
class B
Multilevel Inheritance Example
#include <iostream.h> class derive2 : public derive1
class base //single base class { private:
{public: int z;
int x; public:
void getdata() void indata()
{cout << "Enter value of x= "; { cout << "\nEnter value of z= ";
cin >> x; } cin >> z; }
}; void product()
class derive1 : public base { cout << "\nProduct= " << x * y *
{ public: z; } };
int y; int main()
void readdata() {
{cout << "\nEnter value of y= "; derive2 a;
cin >> y; a.getdata();
} }; a.readdata(); a.indata(); a.product();
return 0; }
Types of
Inheritance
3. Multiple Inheritances:

In Multiple inheritances, a derived class inherits from


multiple base classes. It has properties of both the base
classes.

Class A Class B Base class

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.

In multilevel inheritance, we have multiple parent classes


whereas in in multiple inheritance we have multiple base classes.

For example
Multilevel inheritance : Inheritance of characters by a child from
father and father inheriting characters from his father (grandfather)

Multiple inheritance : Inheritance of characters by a child from


mother and father

Syntax:

class subclass_name : access_mode base_class1, access_mode base_class2,


....
{ //body of subclass };
#include <iostream.h> class C : public A, public B //C is
class A derived from class A and class B
{ public: {
int x; public:
void getx() void sum()
{ cout << "enter value of x: "; { cout << "Sum = " << x + y;
cin >> x; } };
} }; int main()
class B {
{ C obj1; //object of derived class C
public: obj1.getx();
int y; obj1.gety();
void gety() obj1.sum();
{cout << "enter value of y: "; return 0;
cin >> y; }
} };
Types of
Inheritance
4. Hierarchical Inheritance:

In hierarchical Inheritance, it's like an inverted tree. So


multiple classes inherit from a single base class. It's
quite analogous to the File system in a unix based
system.
#include <iostream.h>
class A //single base class class C : public A //C is also
{ derived from class base
public: {
int x, y; public:
void getdata() void sum()
{ cout << "\nEnter value of x {
and y:\n"; cout << "\nSum= " << x + y;
cin >> x >> y; }
} }; };
class B : public A //B is derived int main()
from class base {
{ B obj1; //object of derived class B
public: C obj2; //object of derived class C
void product() obj1.getdata();
{ obj1.product(); obj2.getdata();
cout << "\nProduct= " << x * y; obj2.sum(); return 0; }
} };
Types of
Inheritance
5. Hybrid Inheritance:
✔In this type of inheritance, we can have mixture of
number of inheritances but this can generate an error
of using same name function from no of classes,
which will bother the compiler to how to use the
functions.
✔Therefore, it will generate errors in the program. This
has known as ambiguity or duplicity.
✔Ambiguity problem can be solved by using virtual base
classes
Types of
5. Inheritance
Hybrid
Inheritance:
Class A

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 { void B::show_a(void) {


int a; // private; not inheritable cout << "a = " << a << "\n";
public: }
int b; // public; ready for inheritance // Member function definitions of class D
void get_ab(void); void D::mul(void) {
int get_a(void); c = b * get_a(); // b is inherited from class B
// public accessor for private a }
void show_a(void); void D::display(void) {
}; cout << "a = " << get_a() << "\n";
class D : public B { cout << "b = " << b << "\n";
int c;
cout << "c = " << c << "\n";
public:
}
void mul(void);
void display(void); int main() {
}; D d;
// Member function definitions of class B d.get_ab(); d.mul(); d.show_a(); d.display();
void B::get_ab(void) { d.b = 20;
a = 5; d.mul(); d.display();
b = 10; return 0;
} }
Class D Accessibility
Case of Private Derivation:

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.

⦿ The order of invocation in inheritance is that


the base class’s default constructor will be
invoked first and then the derived class’s
default constructor will be invoked.
// C++ program to show the order of constructor call
// in single inheritance

#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

#include <iostream> class Child : public Parent1, public


using namespace std; Parent2
class Parent1 {
{ public:
public: // child class's Constructor
// first base class's Constructor Child()
Parent1() {
{cout << "Inside first base class" << cout << "Inside child class" << endl;
endl; }};
}}; // main function
// second base class int main() {
class Parent2 // creating object of class Child
{ Child obj1;
public: return 0;
// second base class's Constructor }
Parent2()
{cout << "Inside second base class"
<< endl;
}};
Constructors with arguments in
derived class:
⦿ As long as no base class constructor takes any arguments, the
derived class need not have a constructor function.

⦿ However, if any base class contains a constructor with one or


more arguments, then it is mandatory for the derived class to
have a constructor and pass the arguments to the base class
constructors.
// C++ program to show how to call parameterised Constructor
// of base class when derived class's Constructor is called

// 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:

●Whenever the derived class’s default constructor is called,


the base class’s default constructor is called automatically.

● To call the parameterised constructor of base class inside


the parameterised constructor of sub class, we have to
mention it explicitly.

● The parameterised constructor of base class cannot be


called in default constructor of sub class, it should be called
in the parameterised constructor of sub class.
⦿ C++ constructor call order will be from top to down that is
from base class to derived class and c++ destructor call order
will be in reverse order.
class Device{
public:
Device(){cout<<"Constructor: Device\n";}
Output:
~Device(){cout<<"Destructor : Device\n";}};
class Mobile: public Device{ Constructor: Device
public: Constructor: Mobile
Mobile(){cout<<"Constructor: Mobile\n";} Constructor: Android
~Mobile(){cout<<"Destructor : Mobile\n";} Destructor : Android
}; Destructor : Mobile
class Android: public Mobile{
Destructor : Device
public:
Android(){cout<<"Constructor: Android\n";}
~Android(){cout<<"Destructor : Android\n";}
};
int main()
{
Android _phone; // create the object that will call required constructors
return 0;
}
1. In inheritance, the order of constructors calling
is: from ---------- to -------------

2. In inheritance, the order of constructors


execution is: from ---------- to -------------

3. In inheritance, the order of destructors calling is:


from ---------- to -------------

4. In inheritance, the order of destructors execution


is: from ---------- to -------------
Overriding Member Function
⦿ When the base class and derived class have member functions
with exactly the same name, same return-type, and same
arguments list, then it is said to be function overriding.

⦿ Suppose, the same function is defined in both the derived class


and the based class. Now if we call this function using the
object of the derived class, the function of the derived class is
executed.

⦿ The function in derived class overrides the function in base


class.
Class A {
public:
void display() {
cout<<"Base class"; Output:
}
}; Derived Class

class B:public A {
public:
void display() {
cout<<"Derived Class";
}
};

int main() {
B obj;
obj.display();
return 0;
}
Access Overridden Function in C++

⦿Toaccess the overridden function of the base class, we


use the scope resolution operator
class Base {
public:
void print() { cout << "Base Function" << endl; Output:
} };
class Derived : public Base { Derived Function
public: Base Function
void print() { cout << "Derived Function" << endl;
} };
int main() {
Derived derived1, derived2;
derived1.print();
derived2.Base::print();
return 0;
}
Call Overridden Function From Derived Class

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.

⦿ However ClassD inherit both ClassB & ClassC, therefore


ClassD have two copies of ClassA, one from ClassB and
another from ClassC.

⦿ If we need to access the data member a of ClassA through the


object of ClassD, we must specify the path from which a will
be accessed, whether it is from ClassB or ClassC, bco’z
compiler can’t differentiate between two copies of ClassA in
ClassD.
⦿ There are 2 ways to avoid this ambiguity:

1. Use scope resolution operator

2. Use virtual base class


⦿ Avoiding ambiguity using scope resolution operator:

⦿ Using scope resolution operator we can manually specify the


path from which data member a will be accessed, as shown in
statement 3 and 4, in the example.

obj.ClassB::a = 10; //Statement 3


obj.ClassC::a = 100; //Statement 4

Note : Still, there are two copies of ClassA in ClassD.


So, there is a need of Virtual base class.
Virtual base class in C++
⦿ Virtual base classes are used in virtual inheritance in a way of
preventing multiple “instances” of a given class appearing in
an inheritance hierarchy when using multiple inheritances.
⦿ Need for Virtual Base Classes:

⦿ Consider the situation where we have one class A .This class is A is


inherited by two other classes B and C.

⦿ Both these class are inherited into another in a new class D.

⦿ As we can see from the figure that data members/function of class A


are inherited twice to class D. One through class B and second
through class C.

⦿ When any data / function member of class A is accessed by an object


of class D, ambiguity arises as to which data/function member would
be called? One inherited through B or the other inherited through C.
This confuses compiler and it displays error.
Example To show the need of Virtual Base Class in C++

#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 :

Syntax for Virtual Base Classes:


Syntax 1:
class B : virtual public A
{ };
Syntax 2:
class C : public virtual A
{ };
⦿ When a base class is specified as a virtual base, it can act as an indirect base
more than once without duplication of its data members.

⦿ 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

UML class diagram for EMPLOY.


The database stores a name and an employee identification number for all
employees, no matter what their category. However, for managers, it also
stores their titles and golf club dues.

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.

⦿ The manager and scientist classes contain additional information about


these categories of employee, and member functions to handle this
information
const int LEN = 80; //maximum length of
names void putdata() const
class employee //employee class {
{ cout << “\n Name: “ << name;
private: cout << “\n Number: “ <<
char name[LEN]; //employee name number;
unsigned long number; //employee number }
public: };
void getdata()
{
cout << “\n Enter last name: “; cin >> name;
cout << “ Enter number: “; cin >> number;
}
class manager : public employee class scientist : public employee
//management class //scientist class
{ {
private: private:
char title[LEN]; //”vice-president” etc. int pubs; //number of publications
double dues; //golf club dues public:
public: void getdata()
void getdata() {
{ employee::getdata();
employee::getdata(); cout << “ Enter number of pubs: “; cin >>
cout << “ Enter title: “; cin >> title; pubs;
cout << “ Enter club dues: “; cin >> dues; }
} void putdata() const
void putdata() const {
{ employee::putdata();
employee::putdata(); cout << “\n Number of publications: “ <<
cout << “\n Title: “ << title; pubs;
cout << “\n Golf club dues: “ << dues; }
} };
};
Enter data for manager 1
Enter last name: Bradley
Enter number: 12
class laborer : public employee //laborer class Enter title: Vice-President
{ }; Enter golf club dues: 100000
Enter name of school or university:
int main() Yale
Enter highest degree earned
{ manager m1, m2; (Highschool, Bachelor’s, Master’s,
scientist s1; PhD): Bachelor’s
laborer l1; Enter data for scientist 1
cout << endl; //get data for several employees Enter last name: Twilling
Enter number: 764
cout << “\nEnter data for manager 1”; Enter number of pubs: 99
m1.getdata(); cout << “\nEnter data for manager Enter
2”; name of school or university: MIT
Enter highest degree earned
m2.getdata(); cout << “\nEnter data for scientist 1”;
(Highschool, Bachelor’s, Master’s,
s1.getdata(); cout << “\nEnter data for laborer 1”;PhD): PhD
l1.getdata(); //display data for several employeesEnter data for scientist 2
cout << “\nData on manager 1”; Enter last name: Yang
m1.putdata(); cout << “\nData on manager 2”; Enter number: 845
Enter number of pubs: 101
m2.putdata(); cout << “\nData on scientist 1”; Enter name of school or university:
s1.putdata(); cout << “\nData on laborer 1”; Stanford
l1.putdata(); Enter highest degree earned
(Highschool, Bachelor’s, Master’s,
cout << endl; PhD): Master’s
return 0; Enter data for laborer 1
} Enter last name: Jones
Enter number: 48323
Containership in C++
⦿ We can create an object of one class into another and that
object will be a member of the class. This type of relationship
between classes is known as containership or has_a
relationship as one class contain the object of another class.
And the class which contains the object and members of
another class in this kind of relationship is called a container
class.

⦿ The object that is part of another object is called contained


object, whereas object that contains another object as its part or
attribute is called container object.
Syntax for Containership:
// Class that is to be contained
class first {
.
.
};

// Container class
class second {

// creating object of first


first f;
.
.
};
Example 1:

class first { int main()


public:
{
void showf()
{ // creating object of second
cout << "Hello from first class\n"; second s;
} }
};

// 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.

⦿ These relationships are widely used in Object-Oriented


Programming (OOP) to manage the association between
objects.

⦿ Aggregation is a "has-a" relationship where one object (the


whole) contains other objects (the parts), but the parts can exist
independently of the whole. In other words, the lifetime of the
parts is not controlled by the whole.
Example:
Car side represents aggregation, meaning the Car contains an Engine, but the
Engine can exist independently.

// Part class (Engine)


class Engine { void startCar() {
public:
engine.start();
void start() {
cout << "Engine started." << endl; cout << "Car is running." << endl;
}
}};
};
// Whole class (Car) int main() {
class Car {
Engine engine; // Creating an independent
private:
Engine object
Engine engine; // Aggregation
relationship (Engine object as a Car myCar(engine); // Car aggregates the
member) Engine (passing by value)
public:
myCar.startCar(); // Start the car, which
// Car uses an existing Engine object
Car(Engine eng) : engine(eng) {} starts the engine
return 0;
}
Class hierarchy in UML
Aggregation relationship:

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:

// Aggregating class Manager


class Student {
class Manager {
public:
private:
void study() {
Student stu; // Aggregation
cout << "Student is
Employee emp; // Aggregation
studying." << endl;
public:
}
Manager(Student s, Employee e) :
};
stu(s), emp(e) {}
// Independent class Employee
void manage() {
class Employee {
cout << "Manager is managing the
public:
team." << endl;
void work() {
stu.study();
cout << "Employee is
emp.work();
working." << endl;
}
}
};
};
class Scientist { class Laborer {
private: private:
Student stu; Employee emp;
Employee emp public:
public: Laborer(Employee e) : emp(e) {}
Scientist(Student s, Employee e) : stu(s),
emp(e) {} void labor() {
cout << "Laborer is doing hard
void research() { work." << endl;
cout << "Scientist is conducting emp.work();
research." << endl; }
stu.study(); };
emp.work();
}
};
int main() {

Student stu1;
Employee emp1, emp2;

Manager mgr(stu1, emp1);


mgr.manage(); // Manager manages the team

Scientist sci(stu1, emp2);


sci.research(); // Scientist conducts research

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.

aggregation is a “has a” relationship,


composition is a “consists of” relationship.
Q. make three classes “SimpleCalculator”, “ScientificCalculator” and
“HybridCalculator”.

In “SimpleCalculator” class you have to take input of 2 numbers and


perform function (+, -, *, /)

In “ScientificCalculator” class you have to take input of 2 numbers and


perform any 4 scientific operations

You have to inherit both “SimpleCalculator” and “ScientificCalculator”


classes with the “HybridCalculator” class.
class SimpleCalculator {
int a, b;
public:
void getDataSimple()
{
cout<<"Enter the value of a"<<endl;
cin>>a;
cout<<"Enter the value of b"<<endl;
cin>>b;
}

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.

⦿ Function overloading and operator overloading


is the type of Compile time polymorphism.
⦿ We have two functions with same name but different
number of arguments.

⦿ Based on how many parameters we pass during


function call determines which function is to be
called, this is why it is considered as an example of
polymorphism because in different conditions the
output is different.

⦿ Since, the call is determined during compile time


that's why it is called compile time polymorphism.
#include <iostream>
using namespace std;
class Add {
public: Output:Output: 30
int sum(int num1, int num2){ Output: 66
return num1+num2;
}
int sum(int num1, int num2, int num3){
return num1+num2+num3;
}
};
int main() {
Add obj;
//This will call the first function
cout<<"Output: "<<obj.sum(10, 20)<<endl;
//This will call the second function
cout<<"Output: "<<obj.sum(11, 22, 33);
return 0;
}
Runtime Polymorphism
⦿ Function overriding is an example of Runtime polymorphism.
⦿ Function Overriding: When child class declares a method,
which is already present in the parent class then this is called
function overriding, here child class overrides the parent class.

⦿ In case of function overriding we have two definitions of the


same function, one is parent class and one in child class. The
call to the function is determined at runtime to decide which
definition of the function is to be called, thats the reason it is
called runtime polymorphism. Hence, it is known as late
binding or dynamic binding.
#include <iostream>
using namespace std;
class A { Super Class Function
public: Sub Class Function
void disp(){
cout<<"Super Class Function"<<endl;
}
};
class B: public A{
public:
void disp(){
cout<<"Sub Class Function";
}
};
int main() {
//Parent class object
A obj;
obj.disp();
//Child class object
B obj2;
obj2.disp();
return 0;
}

You might also like