UNIT 3
Object & Classes
Since C++ is an object-oriented language, program is designed using objects and classes in C++.
Object
In C++, Object is a real world entity, for example, chair, car, pen, mobile, laptop etc.
In other words, object is an entity that has state and behaviour. Here, state means data and behaviour means functionality.
Object is a runtime entity, it is created at runtime.
Object is an instance of a class. All the members of the class can be accessed through object.
Let's see an example to create object of student class using s1 as the reference variable.
- Student s1; //creating an object of Student
In this example, Student is the type and s1 is the reference variable that refers to the instance of Student class.
Class
In C++, object is a group of similar objects. It is a template from which objects are created. It can have fields, methods, constructors etc.
Let's see an example of C++ class that has three fields only.
- Class Student
- {
- Public:
- Int id; //field or data member
- Float salary; //field or data member
- String name;//field or data member
- }
Object and Class Example
Let's see an example of class that has two fields: id and name. It creates instance of the class, initializes the object and prints the object value.
- #include <iostream>
- Using namespace std;
- Class Student {
- Public:
- Int id;//data member (also instance variable)
- String name;//data member(also instance variable)
- };
- Int main() {
- Student s1; //creating an object of Student
- s1.id = 201;
- s1.name = "Sonoo Jaiswal";
- Cout<<s1.id<<endl;
- Cout<<s1.name<<endl;
- Return 0;
- }
Output:
201
Sonoo Jaiswal
Class Example: Initialize and Display data through method
Let's see another example of C++ class where we are initializing and displaying object through method.
- #include <iostream>
- Using namespace std;
- Class Student {
- Public:
- Int id;//data member (also instance variable)
- String name;//data member(also instance variable)
- Void insert(int i, string n)
- {
- Id = i;
- Name = n;
- }
- Void display()
- {
- Cout<<id<<" "<<name<<endl;
- }
- };
- Int main(void) {
- Student s1; //creating an object of Student
- Student s2; //creating an object of Student
- s1.insert(201, "Sonoo");
- s2.insert(202, "Nakul");
- s1.display();
- s2.display();
- Return 0;
- }
Output:
201 Sonoo
202 Nakul
Class Example: Store and Display Employee Information
Let's see another example of C++ class where we are storing and displaying employee information using method.
- #include <iostream>
- Using namespace std;
- Class Employee {
- Public:
- Int id;//data member (also instance variable)
- String name;//data member(also instance variable)
- Float salary;
- Void insert(int i, string n, float s)
- {
- Id = i;
- Name = n;
- Salary = s;
- }
- Void display()
- {
- Cout<<id<<" "<<name<<" "<<salary<<endl;
- }
- };
- Int main(void) {
- Employee e1; //creating an object of Employee
- Employee e2; //creating an object of Employee
- e1.insert(201, "Sonoo",990000);
- e2.insert(202, "Nakul", 29000);
- e1.display();
- e2.display();
- Return 0;
- }
Output:
201 Sonoo 990000
202 Nakul 29000
An operator is simply a symbol that is used to perform operations. There can be many types of operations like arithmetic, logical, bitwise etc.
There are following types of operators to perform different types of operations in C language.
- Arithmetic Operators
- Relational Operators
- Logical Operators
- Bitwise Operators
- Assignment Operator
- Unary operator
- Ternary or Conditional Operator
- Misc Operator
Precedence of Operators
The precedence of operator species that which operator will be evaluated first and next. The associativity specifies the operators direction to be evaluated, it may be left to right or right to left.
Let's understand the precedence by the example given below:
- Int data=5+10*10;
The "data" variable will contain 105 because * (multiplicative operator) is evaluated before + (additive operator).
The precedence and associativity of C++ operators is given below:
Category | Operator | Associativity |
Postfix | () [] -> . ++ - - | Left to right |
Unary | + - ! ~ ++ - - (type)* & sizeof | Right to left |
Multiplicative | * / % | Left to right |
Additive | + - | Right to left |
Shift | << >> | Left to right |
Relational | < <= > >= | Left to right |
Equality | == !=/td> | Right to left |
Bitwise AND | & | Left to right |
Bitwise XOR | ^ | Left to right |
Bitwise OR | | | Right to left |
Logical AND | && | Left to right |
Logical OR | || | Left to right |
Conditional | ?: | Right to left |
Assignment | = += -= *= /= %=>>= <<= &= ^= |= | Right to left |
Comma | , | Left to right |
Constructors
- It is a member function of a class with same name as that of a class.
Class example
{
Int x,y;
Public:
Example() //constructor, same name as that of class
{
}
Void display()
{
:
}
};
- It is used to initialize data members of class.
Class example
{
Int x,y;
Public:
Example() //constructor initializing data members of class
{
x=10;
y=20;
}
Void display()
{
:
}
};
- It is always declared under public section.
Class example
{
Private:
Int x,y;
Example() // error, constructor declared under private section
{
x=10;
y=20;
}
:
:
};
- It does not have return type and hence cannot return any value
Class example
{
Int x, y;
Public:
Void example() // error, constructor does not have return type
{
x=10;
y=20;
}
:
:
};
- It is invoked automatically when object of class is created and initialize all data members of a class.
Class example
{
Int x, y;
Public:
Example() // constructor
{
x=10;
y=20;
}
Void display()
{
Cout<<x<<y;
}
};
Int main()
{
Example obj; //invokes constructor and initialize data
Member x and y to 10 and 20 respectively.
Obj.display();
Return 0 ;
}
- It cannot be declared as static, const and virtual.
- It can be defined inside a class or outside the class. While defining it outside the class scope resolution operator is used.
Class example
{
Int x, y;
Public:
Example(); // constructor declared
:
:
};
Example::example(); // constructor defined outside class
{
x=10;
y=20;
}
Types of Constructor
Types of constructors with syntax
Fig: Types of Constructor
Default /Non parameterized Constructor
- A constructor with no parameter is default constructor.
- If constructor is not defined in program then compiler supplies default constructor.
Class Volume
{
Int x;
Public:
Volume () // default constructor
{
x=10;
}
Void display()
{
Cout<<x*x*x;
}
};
Void main()
{
Volume Obj; //invokes default constructor
Obj.display();
}
Parameterized Constructor
A constructor that receives parameters is parameterized constructor.
Class Volume {
Int x;
Public:
Volume ( int a) // parameterized constructor
{
x=a;
}
Void display()
{
Cout<<x*x*x;
}
};
Int main()
{
Volume obj(10); //invokes parameterized constructor
And pass argument 10 to it.
Obj.display();
}
Copy Constructor
Copy constructor initializes an object using values of another object passed to it as a parameter.
Class Volume
{
Int x;
Public:
Volume ( int & P) // copy constructor
{
x=P.x; //copies value
}
Void display()
{
Cout<<x*x*x;
}
};
Int main()
{
Volume obj1; //invokes default constructor
Volume obj2(obj1); //calls copy constructor
Obj2.display();
}
Constructor Overloading
Constructors can be overloaded just like member functions. Thus we can have multiple constructors in a class.
Write a C++ program to find volume of cube, cylinder.
Solution :
#include<iostream>
Using namespace std ;
Class Volume //Defines class Volume
{
Int x,y,z;
Public:
Volume ( int a) // Step 1Constructor with one argument
{
x=a;
}
Volume ( int a, int b) // Step 2 Constructor with two arguments
{
x=a;
y=b;
}
Void displaycube();
Void displaycylinder();
};
Void Volume::displaycube()
// Step 3 Function to calculate volume of cube
{
Cout<<x*x*x;
}
Void Volume::displaycylinder()
//Step 4 Function to calculate volume of cylinder
{
Cout<<3.14*x*x*y;
}
Int main()
{
Volume obj1(10);
// Step 5Calls constructor with one argument.
Volume obj2(10,5);
// Step 6 Calls constructor with two arguments.
Obj1. Displaycube (); //Step 7
Obj2. Displaycylinder ();
Return 0 ;
}
Explanation
This program calculates volume of cube and cylinder. For this we use two constructors in a class. One constructor is to initialize data member for cube and other to initialize data members for cylinder.
Step 1 : Defines constructor with one argument. Here x stands for side of a cube.
Volume ( int a) { x=a; } | //Constructor with one argument
|
Step 2 : Defines constructor with two arguments. Here x and y specifies radius and height.
Volume ( int a, int b) { x=a; y=b; } | //Constructor with two arguments
|
Step 3 : Defines Function to calculate volume of cube.
Void Volume::displaycube() { Cout<<x*x*x; } | //Function to calculate volume of cube
|
Step 4 : Defines Function to calculate volume of cylinder
Void Volume::displaycylinder() { Cout<<3.14*x*x*y; } | //Function to calculate volume of cylinder
|
Step 5 : Here we want to initialize side of cube so we pass only one argument to invoke constructor with one argument.
Volume obj1(10); |
Step 6 : Here we want to initialize radius and height of cylinder so we pass two arguments to invoke constructor with two arguments.
Volume obj2(10,5); |
Step 7 : Calls functions to calculate volume of a cube and cylinder.
Obj1. Displaycube (); Obj2. Displaycylinder (); |
Destructors
- It is a special member function that is called when lifetime of an object ends.
- Destructor is used to free the resources occupied by an object.
- It is called automatically when the object is no longer needed.
- It has same name as that of class preceded by tilde(~).
Class example
{
Public:
~example();//destructor
};
- It is always declared or defined under public section.
- It neither returns any value nor takes any argument.
- It cannot be declared as static const and volatile.
A friend function of a class is defined outside that class' scope but it has the right to access all private and protected members of the class. Even though the prototypes for friend functions appear in the class definition, friends are not member functions.
A friend can be a function, function template, or member function, or a class or class template, in which case the entire class and all of its members are friends.
To declare a function as a friend of a class, precede the function prototype in the class definition with keyword friend as follows −
Class Box {
Double width;
Public:
Double length;
Friend void printWidth( Box box );
Void setWidth( double wid );
};
To declare all member functions of class ClassTwo as friends of class ClassOne, place a following declaration in the definition of class ClassOne −
Friend class ClassTwo;
Consider the following program –
#include <iostream>
Using namespace std;
Class Box {
Double width;
Public:
Friend void printWidth( Box box );
Void setWidth( double wid );
};
// Member function definition
Void Box::setWidth( double wid ) {
Width = wid;
}
// Note: printWidth() is not a member function of any class.
Void printWidth( Box box ) {
/* Because printWidth() is a friend of Box, it can
Directly access any member of this class */
Cout << "Width of box : " << box.width <<endl;
}
// Main function for the program
Int main() {
Box box;
// set box width without member function
Box.setWidth(10.0);
// Use friend function to print the wdith.
PrintWidth( box );
Return 0;
}
When the above code is compiled and executed, it produces the following result −
Width of box : 10
In the above example we can say that “a Manager is-a- type of Employee”, “a Teamleader is-a- type of Employee” and “a Teammember is-a- type of Employee”, etc.
This shows that the manager ,Team Leader, Team member and Employee share some common attributes and behaviors.
The concept of inheritance have parent class which act as generic super class or an abstract class having the common attributes and methods inherited to child class or all sub classes.
Class Manager, TeamLeader and class TeamMember inherits all common attributes and functions written in Employee class. The sub classes can have their own aatributes and function in addition to the super class attributes and functions.
The word polymorphism means having many forms. Typically, polymorphism occurs when there is a hierarchy of classes and they are related by inheritance.
C++ polymorphism means that a call to a member function will cause a different function to be executed depending on the type of object that invokes the function.
Consider the following example where a base class has been derived by other two classes −
#include <iostream>
Using namespace std;
Class Shape {
Protected:
Int width, height;
Public:
Shape( int a = 0, int b = 0){
Width = a;
Height = b;
}
Int area() {
Cout << "Parent class area :" <<endl;
Return 0;
}
};
Class Rectangle: public Shape {
Public:
Rectangle( int a = 0, int b = 0):Shape(a, b) { }
Int area () {
Cout << "Rectangle class area :" <<endl;
Return (width * height);
}
};
Class Triangle: public Shape {
Public:
Triangle( int a = 0, int b = 0):Shape(a, b) { }
Int area () {
Cout << "Triangle class area :" <<endl;
Return (width * height / 2);
}
};
// Main function for the program
Int main() {
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// store the address of Rectangle
Shape = &rec;
// call rectangle area.
Shape->area();
// store the address of Triangle
Shape = &tri;
// call triangle area.
Shape->area();
Return 0;
}
When the above code is compiled and executed, it produces the following result −
Parent class area :
Parent class area :
Operator Overloading
Introduction and Need of Operator Overloading
- Operators have fixed meaning and functionalities for primitive data types like int, float, double etc.
- These operators cannot be used for user defined data types like classes.
- But the functionality of these operators can be extended to user defined data types like classes.
- Operator ‘+’ is used to add two integers but we can add two objects by extending the meaning of ‘+’ operator.
- This is called as operator overloading.
- We can overload operators so that they can perform operation on objects.
- Operator overloading provides special meaning to built in operators to perform some specific computation when the operator is used on objects of that class.
- All C++ operators can be overloaded except following :
- Class member access operator(.*)
- Conditional operator(?:)
- Scope resolution operator(::)
- Size of operator(sizeof)
Operator Function
- Operator is overloaded with the help of operator function.
- It defines the operations to be performed by overloaded operator.
- This operator function can be of two types
1. Member operator function
2. Non Member operator function
- Non member operator functions are usually friend functions of class. Operator functions are discussed in preceding section.
Overloading using Member Operator Function
Syntax of an operator function
- Member operator function is a member of the class.
- It is declared in a class as follows :
Return-type operator OP(argument list);
Where OP -> operator to be overloaded.
- Number of parameters in an argument list depends on the type of operator.
Type of Operator | No. Of Arguments |
Unary | 0 |
Binary | 1 |
- Thus according to above table, overloading unary operators using member functions takes no argument and binary operator takes one argument.
- It is defined as follows :
Return-type class-name :: operator OP(argument list)
{
Operations that overloaded operator performs
}
Overloading Unary Operators using Member Operator Function
Member operator function takes no parameter for unary operator and is implicitly passed through “this” pointer.
Overloading Unary Minus(–)
Program
Write a program in C++ to overload unary minus(-).
Solution :
#include<iostream> Using namespace std ; Class Example { Int x,y,z; Public:
Example(int p,int q,int r) { x=p; y=q; z=r; } Void display() { Cout<<x<<” ”<<y<<” ”<<z; } Void operator-() { x=-x; y=-y; z=-z; } }; Int main() { Example obj (10,-20,30); Cout<<”Original numbers are” Obj.display(); - obj; Obj.display(); Return 0; } |
//Defines class Example
//Parameterized constructor
// Step 1 Operator function to overload minus
// Step 2 Invokes operator function
Cout<<”Numbers after applying unary minus” |
Explanation
- This program overloads unary – on data members of class Example.
- It defines operator function to overload unary – so that it can be applied to object. See step 1.
Void operator-() { x=-x; y=-y; z=-z; } | //Operator function to overload minus
|
- This operator function is invoked by applying unary – on object ‘obj’. See step 2.
- obj; Cout<<”Numbers after applying unary minus” | //Invokes operator function |
Output
Original numbers are
10 -20 30
Numbers after applying unary minus
-10 20 -30
Overloading ++ and – –
- ++ and – –are unary operators so member operator function will take no arguments.
- ++(increment operator) and – – (decrement operator)takes two forms via postfix and prefix. So member operator function for each version must be written separately.
- It is discussed below.
Overloading Prefix versions
Prefix increment
Return-type operator ++()
{
//Body of operator function
}
Example
Void operator++()
{
---
}
Prefix decrement
Return-type operator --()
{
//Body of operator function
}
Example
Void operator--()
{
---
}
Postfix versions
Post Increment
Return-type operator ++(int x)
{
//Body of operator function
}
Where x is zero.
Example
Void operator ++(int x)
{
---
}
Post Decrement
Return-type operator --(int x)
{
//Body of operator function
}
Example
Void operator--(int x)
{
---
}
Program
Write a C++ program to overload ++,-- (postfix and prefix versions), !
(logical not) operator.
#include<iostream> Using namespace std ; Class Example Int a,b; Public: Void accept() { Cout<<”enter values of and b”; Cin>>a>>b; } Void display() { Cout<<a<<” ”<<b<<” ”; } Void operator++(); Void operator--(); Void operator++(int x); Void operator--(int x); Void operator!(); }; Void Example:: operator++() { a=++a; b=++b; } Void Example:: operator--() { a=--a; b=--b; } Void Example:: operator++(int x) { a=a++; b=b++; } Void Example:: operator--(int x) { a=a--; b=b--; } Void Example:: operator!() { a=!a; b=!b; } Int main() { Example O; Obj.accept(); ++ O; Obj.display(); Obj ++; obj.display(); -- obj; Obj.display(); Obj --; Obj.display(); ! obj; Obj.display(); Return 0; } |
//overloads prefix ++ //overloads prefix -- //overloads postfix ++ //overloads postfix -- //overloads logical not
//Defines operator function to overload prefix version of ++
//Defines operator function to overload prefix version of --
//Defines operator function to overload postfix version of ++
//Defines operator function to overload postfix version of --
//Defines operator function to overload logical not
//Invokes operator Functions to perform ++ --(postfix and prefix)and ‘!’ On object ‘obj’. |
Overloading Binary Operators using Member Operator Function
- Member operator function takes only one parameter for binary operator as left hand side operand is implicitly passed through this pointer.
- Left hand side object is responsible to invoke operator function.
- Overloading plus(+) and minus(–)
- We can perform addition and subtraction on two objects by overloading + and -.
Program
Write a C++ program to overload binary +, - .
#include<iostream> Using namespace std ; Class Example { Int a,b; Public: Example(int p, int q) { a=p; b=q; } Void display() { Cout<<a<<” ”<<b<<endl; } Example operator+(Example X); Example operator-(Example X); }; Example Example::operator+(Example X) { Example E; E.a= a+X.a; E.b= b+X.b; Return E } Example Example:: operator-(Example X) { Example F; F.a= a-X.a; F.b= b-X.b; Return F } Int main() { Example obj1(10,20); Example obj2(5,5); Example obj3(0,0); Cout<<”Addition is” Obj3= obj1+ obj2; Obj3.display(); Cout<<”Subtraction is” Obj3= obj1- obj2; Obj3.display(); Return 0 ; } |
// Step 1 overloads + // Step 1 overloads -
// Step 2 Defines operator function to overload +
//Defines operator function to overload -
// Step 3 //Invokes overloaded binary +
// Step4 //Invokes overloaded binary -
|
Explanation
- This program overloads binary + and -. For this operator functions are declared in class. See step 1.
- This operator function returns objects which stores addition of two objects.
Return type of an object is always a class so it is declared as follows
Example operator+(Example X); Example operator-(Example X); | //overloads + //overloads - |
Example Operator + (Example X )
Return type operator to be overloaded
Function
Argument list
- Operator functions are defined outside class using scope resolution operator. See step 2.
Example Example:: operator+(Example X) { Example E; E.a= a+X.a; E.b= b+X.b; Return E; } Example Example:: operator-(Example X) { Example F; F.a= a-X.a; F.b= b-X.b; Return F;
} | //Defines operator function to overload +
//Defines operator function to overload -
|
- Operator function takes only one argument as left hand side operand is passed implicitly via this pointer.
- This operator function returns object where addition is stored.
- Return type of an object is always a class so it is declared as follows :
Example | Operator | + | (Example X ) |
Return type |
Function |
Operator |
Argument list
|
- Operator function for addition is activated when two objects are added using +. See
step 3.
O3= O1+ O2;
| //Invokes overloaded binary + |
- Operator function for subtraction is activated when two objects are subtracted using -. See step 4.
O3= O1- O2; | //Invokes overloaded binary - |
Thus the output will be :
Output
Cout<<”Addition is”
a 15 b 25
Cout<<”Subtraction is”
a 5 b 15
Program
Write C++ program to demonstrate use of binary (“+”) operator overloading to add two complex numbers using member function.
#include<iostream> Using namespace std ; Class Demo { Int real,imag; Public: Demo(int p, int q) { Real=p; Imag=q; } Void display() { Cout<<real<<” +j”<<imag<<endl; } Demo operator+(Demo X); }; Demo Demo::operator+(Demo X) { Demo D; D.real=real+X.real; D.imag=imag+D.imag; Return D } Int main() { Demo obj1(10,20); Demo obj2(5,5); Demo obj3(0,0); Cout<<”Addition is” Obj3= obj1+ obj2; Obj3.display(); Return 0 ; } |
//……1overloads +
//.2 Defines operator function to overload +
//Defines operator function to overload -
//…..3 //Invokes overloaded binary +
|
Operator Overloading using Friend Function
- Unary Operators
- Operator function to overload unary operator using friend function takes one argument.
Example
Friend void operator-(Example &O);
Program
Write a program to overload unary –, ++,--(prefix versions) using friend function.
#include<iostream> Using namespace std ; Class Example { Int x,y,z; Public: Example(int p,int q,int r) { x=p; y=q; z=r; } Void display() { Cout<<x<<” ”<<y<<” ”<<z; } Friend void operator-(Example &O); Friend void operator++(Example &O); Friend void operator--(Example &O); }; Void operator-(Example & O) { O.x=-O.x; O.y=-O.y; O.z=-O.z;
} Void operator++(Example & O) { O.x=O.x++; O.y=O.y++; O.z=O.z++; }
Void operator--(Example & O) { O.x=O.x--; O.y=O.y--; O.z=O.z--; } }; Int main() { Example O(10,-20,30); Cout<<”Original numbers are”; O.display(); - O; Cout<<”Numbers after applying unary minus”; O.display(); ++ O; Cout<<”Numbers after applying ++”; O.display(); -- O; Cout<<”Numbers after applying --”; O.display(); Return 0 ; } |
//Defines class Example
//Parameterized constructor
//Operator functions to overload
//Invokes operator function for –
//Invokes operator function for ++
//Invokes operator function for -- |
Explanation
- Friend Function does not have this pointer. Thus if we attempt to modify value of an object as an argument to a friend function, changes are made to copy of that object and not on original object.
- To reflect changes directly to original object, we are using reference parameter in operator friend function.
- If we overload postfix versions of ++ and – – then operator function will be written as friend Example operator ++(Example &O, int x)
2. Binary Operators
- Operator function to overload binary operator using friend function takes two arguments.
- E.g. Friend void operator-(Example O1, Example O2);
#include<iostream> Using namespace std ; Class Point { Int x,y; Public: Point() {} Point(int p, int q) { x=p; y=q; }
Void display() { Cout<<x<<” ”<<y<<endl; } Friend Point operator+(Point P1,Point P2); Friend Point operator-(Point P1,Point P2); }; Point operator+(Point P1,Point P2) { Point E; E.x= P1.x+P2.x; E.y= P1.y+P2.y; Return E; } Point operator-(Point P1,Point P2) { Point E; E.x= P1.x-P2.x; E.y= P1.y-P2.y; Return E; } Int main() { Example obj1(10,20); Example obj2(5,5); Example obj3(0,0); Obj3= obj1+ obj2; Obj3.display(); Obj3= obj1- obj2; Obj3.display(); Return 0; } |
//Step 1 overloads + using friend
// Step 2 overloads – using friend //Defines operator function to overload +
//Defines operator function to overload -
//Invokes overloaded binary +
//Invokes overloaded binary - |
Explanation
- Here we are overloading binary operators using friend, hence it takes two arguments. Here arguments are objects as usually friend functions take object as arguments. See steps 1 and 2.
Friend Point operator+(Point P1,Point P2); Friend Point operator-(Point P1,Point P2); | //overloads + using friend //overloads – using friend
|
- Operator function returns object E. Return type of object is always a class. Hence return type of operation function will be class “Point” to which object “E” belongs.
- Hence friend function is declared as follows :
- Following operators cannot be overloaded using friends :
1. () Function call operator
2. = Assignment operator
3. [] subscripting operator
4. -> class member access operator
- The chart given below summarizes no of arguments in operator function :
Type of operator Type Of operator Function | Unary | Binary |
Member Function | 0 | 1 |
Friend Function | 1 | 2 |
Program
Write a C++ program to add the complex numbers using friend function.
#include<iostream> Using namespace std ; Class Example { Int real, imag; Public: Example(int p, int q) { Real=p; Imag=q; } Void display() { Cout<<real<<“”<<imag<<endl; } Friend Example operator+(Example X1,Example X2); }; Example operator+(Example X1, Example X2) { Example E; E.real= X1.real+X2.real; E.imag= X1.imag+X2.imag; Return E; } Int main() { Example obj1(10,20); Example obj2(5,5); Example obj3(0,0); Cout<<“Addition is” Obj3= obj1+ obj2; Obj 3.display(); Return 0; } |
//Defines operator function to overload+
//Invokes overloaded binary+
|
Program
Write a C++ program to subtract 2 complex numbers using concept of overloading using friends function.
Solution :
#include<iostream> Using namespace std ; Class Example { Int real, imag; Public: Example(int p, int q) { Real=p; Imag=q; } Void display() { Cout<<real<<”+j”<<imag<<endl; } Friend Example operator-(Example X1,Example X2); }; Example operator-(Example X1, Example X2) { Example E; E.real= X1.real-X2.real; E.imag= X1.imag-X2.imag; Return E; } Int main() { Example obj1(10,20); Example obj2(5,5); Example obj3(0,0); Cout<<“Subtraction is” Obj3= obj1- obj2; Obj3.display(); Return 0; } |
//Defines operator function to overload -
//Invokes overloaded binary -
|
Overloading Relational and Logical Operators
- There are six relational operators in C++
Equality(==)
Less than(<)
Less than equal to(<=)
Greater than(>)
Greater than equal to(>=)
Inequality(!=)
- There are three logical operators
Logical AND (&&)
Logical OR (||)
Logical NOT (!)
- We can overload relational operators <,>,<=,>=, == which can be used to compare the objects of class.
- We will overload only equality and less than operator. Others can be implemented using these two operators by following techniques.
a!=b return !(a==b)
a>b return(b<a)
a<=b return!(b<a)
a>=b return!(a<b)
- Relational and logical operators can be overloaded using following skeleton
Bool class_name::operator symbol(const class_name & rhs)
{
Compare this and rhs and return true and false accordingly
}
Where rhs= right hand side operand
- Overloading of’ =’ , ‘&& ’ and ’ <’ operators is shown below.
#include<iostream>
Using namespace std;
Class overload
{
Private:
Int a,b;
Public:
Overload (int x, int y) //constructor to initialize variables
{
a=x;
b=y;
}
Bool operator <(const overload &o1) // overloading < operator
{
If( (a<o1.a)&&(b<o1.b))
{
Return true;
Else
Return false;
}
Bool operator ==(const overload &o1) // overloading == operator
{
Return ((a==o1.a)&&(b==o1.b));
}
};
Int main()
{
Overload object1(10,20);
Overload object2(11,21);
If(object1<object2) // Compare two objects
Cout<<”Values of object 1 are less than values of Object2”;
Else
Cout<<”Values of object 1 are not less than values of Object2”;
If(object1==object2)
Cout<<”Values of object 1 are equal to values of Object2”;
Else
Cout<<”Values of object 1 are not equal to values of Object2”;
Return 0;
}
Overloading new delete and Assignment Operator
- Overloading New and Delete
New and delete operators can be overloaded using following code.
Void *operator new(size_t size)
{
Return malloc(size); //Perform allocation
}
Where size is number of bytes of memory of data type size_t.
Return type of overloaded new must be void* as it must return pointer to memory that it allocates or throw bad_alloc exception if an allocation error occurs.
Void *operator delete(void *P)
{
Free(*P); // free memory pointed by P
}
Where *P is a pointer to memory to be freed.
Program
Program to overload new and delete operator.
#include<iostream>
Using namespace std;
Class Employee
{
Int id;
Int salary;
Public:
Employee(int x, int y)
{
Id=x;
Salary=y;
}
Void display()
{
Cout<<”Employee id:”<<id<<endl;
Cout<<”Employee salary:”<<salary<<endl;
}
Void *operator new(size_t size );
Void operator delete(void *p);
};
Void *Employee::operator new(size_t size )
{
Void *p;
Cout<<”Overloading new”<<endl;
p=malloc(size);
If(!p)
{
Bad_alloc b;
Throw b;
}
Return p;
}
Void Employee:: operator delete(void *p)
{
Cout<<”Overloading delete”<<endl;
Free(p);
}
Int main()
{
Employee *E1,*E2;
Try
{
E1= new Employee(10,50000);
}catch(bad_alloc ba)
{
Cout<<”Allocation error for E1”;
Return 1;
}
Try
{
E2= new Employee(11,60000);
}catch(bad_alloc ba)
{
Cout<<”Allocation error for E2”;
Return 1;
}
E1->display();
E2->display();
Delete E1;
Delete E2;
Return 0;
}
Output
Overloading new
Overloading new
10 50000
11 60000
Overloading delete
Overloading delete
2. Overloading Assignment Operator
We can assign one object to another by overloading assignment operator.
Program
Write a C++ program to overload assignment operator(=) .
#include<iostream> Using namespace std ; Class Example { Int a,b; Public: Example(int p, int q) { a=p; b=q; }
Void display() { Cout<<a<<” ”<<b<<endl; } Example operator=(Example X); }; Example Example:: operator=(Example X) { a= X.a; b= X.b; Return this*; } Int main() { Example obj1(10,20); Example obj2(0,0); Cout<<”Before Assignment”;
Obj2.display(); Obj2= obj1; Cout<<”After Assignment”; Obj2.display(); Return 0; } |
//parameterized constructor
// Step 1 overloads =
// Step 2 Defines operator function to overload =
// Step 3 Invokes overloaded assignment operator |
Explanation
- Operator function for assignment operator is declared in a class. See step 1.
- This operator function returns object on which assignment operator is applied.
- Return type of an object is always a class so it is declared as follows :
Example operator=(Example X);
Return type Argument list
Function
- Operator function is defined as follows .See step 2
Example Example:: operator=(Example X)
{
a= X.a;
b= X.b;
Return this*;
}
- Here assignment operation is performed on data members of object. This object is returned through this * pointer. It points to an object that generated call to operator function.
- Operator function is invoked by statement obj2= obj1 . See step 3.
- The object returned by this pointer in step 2 is then assigned to object obj2.
- It is then displayed using statement
- Obj2.display();
- C++ provides overloaded assignment operation by default, even if it is not explicitly overloaded.
Output
Before Assignment
a 0 b 0
After Assignment
a 10 b 20
Rules of Operator Overloading
Operators which cannot be overloaded
All C++ operators can be overloaded except following
- Class member access operator(.*)
- Conditional operator(?:)
- Scope resolution operator(::)
- Size of operator(sizeof)
Operators which cannot be overloaded by using Friend Function
Following operators cannot be overloaded using friends
- () Function call operator
- = Assignment operator
- [] subscripting operator
- -> class member access operator
Rules for operator overloading
- Some operators like (assignment)=, (address)& and comma (,) are by default overloaded.
- We cannot create new operators for overloading. Only built in operators can be overloaded.
- We cannot redefine meaning of in built operators i.e we cannot change the meaning +, - etc.
- Precedence and associativity of operators cannot be changed.
- Overloaded operators cannot have default arguments.
- Operators overloaded using member functions takes no argument for unary and one argument for binary operator.
- Operators overloaded using friend functions takes one argument for unary and two arguments for binary operator.
Function Overloading
- Function overloading is one of the way to achieve compile time polymorphism in c++.
- Overloaded functions have same function name and different argument list.
F1→ void accept(int x);
F2→ void accept(float y);
F3→ void accept(int x, int y);
Here accept function is overloaded.
- F1 and F2 are overloaded as they have same function name but different argument list.
- Though argument list consists of single argument it is of different data type.
- F1 and F3 are overloaded as they have same function name and number of arguments are different.
- F2 and F3 are overloaded as they have same function name and number of arguments are different.
- Argument list may have different number of arguments OR different data type of arguments OR both.
- Return type of functions may be same or different.
Int add(int x, int y);
Float add(int x, int y);
Here add functions have different return types but they have same argument list. So they are not overloaded functions.
Thus return type does not play any role in function overloading.
- Overloaded functions perform tasks of similar nature.
- As all overloaded functions have same name compiler determines the function to be called on the basis of argument list.
- Compiler searches for the exact match of function prototype and then executes corresponding function.
Table : Function prototypes and required function calls
Sr. No. | Function Protoypes | Function calls |
1. | Void accept(int x); | Accept(10); |
2. | Void accept(float y); | Accept(1.5); |
3. | Void accept(int x, int y); | Accept(10,20); |
Program
Write a C++ program to calculate the area of circle, rectangle and triangle using function overloading.
Solution :
#include<iostream>
Using namespace std ;
#include<conio.h>
#define pi 3.14
Class Sample //Defines class Sample
{
Public:
Void area(int x) // 1.Calculates area of circle
{
Int y= pi*x*x;
Cout<<“Area of circle is ”<<y;
}
Void area(int a, int b) // 2.Calculates area of rectangle
{
Int c= a*b;
Cout<<“Area of rectangle is”<<c;
}
Void area(float p,float q) // 3.Calculates area of triangle
{
Int s= 0.5*p*q;
Cout<<“area of triangle is”<<s;
}
};
Int main()
{
Sample obj ;
Obj.area(10); // Step 4 Function call for area for circle
Obj.area(10,20); // Function call for area for rectangle
Obj.area(1.5,2.5); // Function call for area for triangle
Return0 ;
}
Explanation
This program calculates area for circle, rectangle and triangle. For this we are overloading “area” function.
Step 1 : Here x denotes radius of circle. This version of “area” calculates area of circle and hence radius is passed as parameter.
Void area(int x) { Int y= pi*x*x; Cout<<“Area of circle is”<<y; } |
//Calculates area of circle
|
Step 2 : Here a and b denote length and breadth of rectangle. This version of “area” calculates area of rectangle and hence length and breadth are passed as parameters.
Void area(int a,int b) { Int c= a*b; Cout<<“Area of rectangle is”<<c; } |
//Calculates area of Rectangle |
Step 3 : Here p and q denote base and height of triangle. This version of “area” calculates area of triangle and hence base and height are passed as parameters.
Void area(float p,float q) { Int s= 0.5*p*q; Cout<<“area of triangle is”<<s; } |
//Calculates area of triangle |
Step 4 : It denotes function calls for different versions of area depending upon type of geometrical figure.
Int main() { Sample obj; Obj.area(10); Obj.area(10,20); Obj.area(1.5,2.5); Return0; } |
//Function call for area for circle //Function call for area for rectangle //Function call for area for triangle |
Single Inheritance
● It consists of single base and single derived class.
● Derived class inherits all the protected and public members from single base class.
● Private data members of base class will not be inherited.
☞ General form
Class derived-class : access specifier base-class
{
//Body of derived class
};
Fig: Single Inheritance
| Class A { //Body of class A }; Class B : public A { //Body of class B }; |
⮚
Program
Write a program in C++ to illustrate single inheritance.
⮚
⮚
⮚
Solution :
#include<iostream> Using namespace std ; Class Employee { Protected: Int id; Char name[10]; Public: Void accept() { Cout<<“Enter id of employee”; Cin>>id; Cout<<“Enter name of employee”; Cin>>name; } }; Class Salary: public Employee { Protected: Float amount, hra, da, basic; Public: Void getdata() { Accept(); Cout<<“enter basic, da and hra”; Cin>>basic>>da>>hra; } Void display() { Amount=basic+da+hra; Cout<<“NAME:”<<name<<endl; Cout<<“ID:”<<id<<endl; Cout<<“SALARY:”<<amount; } }; Int main() { Salary S; S.getdata(); S.display(); Return 0 ; } | //Declares header file
//Step 1 Declares and defines base class Employee
//Step 2 Declares id and name under protected section
//Step 3 Defines accept function under public section
//Accepting id and name of employee
//End of accept function //End of class Employee //Step 4 Create derived class Salary from base class Employee
//Step 5 Declares data members under protected section
//Step 6 Defines getdata function
//Step 7 Calls accept function //Accepting details of salary
//End of getdata function //Step 8 Defines display function
//Calculates salary
//Displaying name id and salary of employee
//End of display function //End of derived class salary //Starts main function
//Step 9 Creates object S //Step 10 Calls getdata function //Calls display function |
Explanation
Step 1 : Creates base class Employee.
As it is single inheritance only one base class is there.
Class Employee //Declares and defines base class Employee
Step 2 : id and name are declared under protected section so that they are accessible to its immediate derived class .
Protected:
Int id; //Declares id and name under protected section
Char name[10];
Step 3 : Accept function accepts details of employee.
Void accept() //Defines accept function under public section
{
Cout<<“Enter id of employee”;
//Accepting id and name of employee
Cin>>id;
Cout<<“Enter name of employee”;
Cin>>name;
} //End of accept function
Step 4 : Creates derived class Salary from base class under public derivation.
All protected members remains protected and public members remain public in public derivation.
Class Salary: public Employee
//Create derived class Salary from base class Employee
So data members in class Salary are as follows :
Salary | |
Protected | Public |
Id Name Amount Hra Da Basic |
Accept() Getdata() Display() |
Step 5 : Declares basic, hra, da for calculation of salary.
Float amount, hra, da, basic;
Step 6 : getdata accepts hra, da and basic to calculate salary.
Void getdata() //Defines getdata function
Step 7 : getdata() calls accept() to get id and name.
Member function can call another member function of same class or base class directly.
Getdata() calls accept() directly as it belongs to base class.
Accept(); //Calls accept function
Cout<<“enter basic, da and hra”;
Cin>>basic>>da>>hra; //Accepting details of salary
Step 8 : Calculates salary and displays details of employee
Void display() //Defines display function
{
Amount=basic+da+hra; //Calculates salary
Cout<<“NAME:”<<name<<endl;
//Displaying name id and salary of employee
Cout<<“ID:”<<id<<endl;
Cout<<“SALARY:”<<amount;
} //End of display function
Step 9 : Creates object of derived class Salary.
In inheritance object of derived class is created because derived class has access to base class but base class does not have any knowledge of its derived classes down the hierarchy.
Salary S; //Creates object S
Step 10 : Calls member functions with the help of objects and dot operator.
S.getdata(); //Calls getdata function
S.display(); //Calls display function
Multiple Inheritance
Q. Explain multiple inheritance in detail with syntax.
☞ Multiple inheritance with syntax
● It consists of multiple base classes and single derived class.
● Derived class inherits protected and public members from multiple base classes.
● If there are two base classes, then derived class inherits features from both the classes.
☞ General form
Class derived-class : access specifier base-class1, access specifier base-class2
{
//Body of derived class
};
Fig: Multiple Inheritance
| Class A { //Body of class A }; Class B { //Body of class B }; Class C : public A, public B { //Body of class C }; |
⮚ Program
Write a C++ program to illustrate multiple inheritance.
Fig. P. 5.4.2
Solution :
Fig. P. 5.4.2shows multiple inheritance where Employee, Person, Manager are classes and name, age, Department, salary, are data members of these classes.
#include<iostream> Using namespace std ; Class Person { Protected: Char Name[10]; Int age; Public: Void accept() { Cout<<“Enter name of person”; Cin>>Name; Cout<<“Enter age of person”; Cin>> age; } }; Class Employee { Protected: Char dept[20]; Public: Void getdata() { Cout<<“Enter department of employee”; Cin>> dept; } }; Class Manager : public Person ,public Employee { Protected: Int salary; Public: Void acceptdata() { Cout<<“Enter salary of employee”; Cin>>salary; } Void display() { Cout<<“Name of Manager is”<<name; Cout<<“Age of Manager is”<<age; Cout<<“Department of Manager is”<<dept; Cout<<“Salary of Manager is”<<salary; } }; Int main() { Manager obj; Obj.accept(); Obj.getdata(); Obj.acceptdata(); Obj.display(); Return 0; } |
//Step 1 Defines base class Person
//Accept details of Person
//Step 2 Defines another base class Employee
//Accept details of Employee
//Step 3 Defines sub class Manager
//Accept details of salary
//Displays details of Manager
//Defines main function
//Creates object of Manager //Access member functions of classes to display details of Manager. |
Explanation
Step 1 : Defines base class Person with data members name and age and function accept().
Data members are declared under protected section so that they are accessible to derived class.
Class Person { Protected: Char Name[10]; Int age; Public: Void accept() { Cout<<“Enter name of person”; Cin>>Name; Cout<<“Enter age of person”; Cin>> age; } }; | //Defines base class Person
//Accept details of Person
|
Step 2 : Defines another base class Employee.
Class Employee { Protected: Char dept[20]; Public: Void getdata() { Cout<<“Enter department of employee”; Cin>> dept; }}; | //Defines another base class Employee
//Accept details of Employee
|
Step 3 : Defines sub class Manager that is derived from two classes Person and Employee.
● Data member is salary.
● acceptdata() function accepts salary of employee.
● display() function displays all the details of Manager.
● display() function of subclass Manager can access all the data members of super classes as they are declared under protected section and inherited under public derivation.
Class Manager : public Person ,public Employee { Protected: Int salary; Public: Void acceptdata() { Cout<<“Enter salary of employee”; Cin>>salary; } Void display() { Cout<<“Name of Manager is”<<name; Cout<<“Age of Manager is”<<age; Cout<<“Department of Manager is”<<dept; Cout<<“Salary of Manager is”<<salary; } }; | //Defines sub class Manager
//Accept details of salary
//Displays details of Manager
|
Step 4 : Creates object of derived class .This object can access all the public and protected data members and member functions of super classes.
Manager obj; | //Creates object of Manager |
Step 5 : Calls accept() function.
Obj.accept(); |
Step 6 : Calls getdata() function.
Obj.getdata(); |
Step 7 : Calls acceptdata() function.
Obj.acceptdata(); |
Step 8 : Calls display()function.
Obj.display(); |
- Virtual function is used to implement run time polymorphism in C++.
- It is declared and defined in a base class and redefined in a derived class.
- It is declared using keyword virtual in following manner :
Virtual return-type function-name(argument list);
- Derived class redefines virtual function to suit its own requirements.
- Virtual functions are accessed via base class pointer to achieve run time polymorphism.
- However they can also be accessed through object just like other member functions but then it will not achieve run time polymorphism.
- This is shown in program given below :
Class Base { Public: Void Data() { Cout<<”Base class”; } }; Class Derived: public Base { Public: Void Data() { Cout<<”Derived class”; } }; Void main() { Base *b; Derived d; b->Data(); b= &d;
b->Data (); } | //Defines Base class
//Defines function Data of Base class
//Defines “Derived” class that is sub class of “Base”.
//Defines function Data of “Derived” class
// Step 1Creates base class pointer //Creates object of derived class // Step 2 Calls Data function with base class pointer // Step 3 Assigns address of derived class object
// Step 4 |
Explanation
- This program consists of two classes “Base” and “Derived” related by single inheritance.
- Both classes define function “Data” to suit their requirement.
Step 1: *b is base class pointer and d is derived class object.
Step 2: b->Data(); calls ”Data ” function of base class..
Step 3: b= &d; points to derived class object.
Step 4: b->Data(); calls member function “Data” of base class even though b points to derived class object.
- Hence the output of above program is given below.
Output
Base class
Base class
- If we want to call derived class version of “Data” function then we need to declare it as virtual.
- The version of virtual function to be called is determined by the type of object pointed to by pointer. The program demonstrating virtual function is as follows :
Class Base { Public: Virtual void Data() { Cout<<”Base class”; } }; Class Derived: public Base { Public: Void Data() { Cout<<”Derived class”; } }; Void main() { Base *b,a;
Derived d;
b= &a;
b->Data();
b= &d;
b->Data (); } | //Defines Base class
//Defines virtual function Data of Base class
//Defines “Derived” class that is sub class of “Base”.
//Redefines virtual function “Data”
//Step 1 Creates base class pointer and object
//Creates object of derived class // Step 2 Points to base class
// Step 3 Calls Data function of Base class
// Step 4 Points to Derived class
// Step 5 Calls Data function of Derived class
|
Explanation
- In this program virtual function “Data” is declared in Base class.
- Both classes define function “Data” to suit their requirement.
Step 1: *b and a represent base class pointer and object respectively.
d is derived class object.
Step 2: b=&a; points to base class.
Step 3: b->Data calls base class version of Data() function.
Step 4: b= &d; points to derived class object.
Step 5: b->Data calls derived class version of Data() function.
Hence the output of above program will be
Output
Base class;
Derived class
Virtual keyword is not required when derived class redefines virtual function. However we can write it but it’s just not mandatory.
Program 6.4.1
Write a C++ program to illustrate Virtual functions.
Fig.
Solution :
#include<iostream> Using namespace std; Class Person { Protected: Int age; Char name[20]; Public: Void accept() { Cout<<”Enter name”; Cin>>name; Cout<<”Enter age ”; Cin>>age; } Virtual void display() {
} }; Class Staff: public Person { Protected: Int exp; Float salary; Public: Void getdata() { Cout<<”Enter experience and salary”; Cin>>exp>>salary; } Void display() { Cout<<”NAME:”<<name<<endl; Cout<<”AGE:”<<age<<endl; Cout<<”Experience:”<<exp; Cout<<”SALARY:”<<salary; } }; Class Student: public Person { Protected: Int marks,grade; Public: Void getdata1() { Cout<<”Enter marks and grade”; Cin>>marks>>grade; } Void display() { Cout<<”NAME:”<<name<<endl; Cout<<”AGE:”<<age<<endl; Cout<<”GRADE:”<<grade; Cout<<”MARKS:”<<marks; } }; Int main() { Person *p,b; Staff obj1; Student obj2; b.accept(); Obj1.getdata(); p=& obj1; p->display(); Obj2.getdata1(); p=& obj2; p->display(); Return 0; } | //Declares header file
//Declares and defines base class Person
//Declares age and name under protected section
//Defines accept function under public section
//Accepting age and name of Person
//End of accept function //Declares Virtual function
//Empty virtual function
//End of class person //Create derived class Staff from base class Person //Declares data members under protected section
//Defines getdata function
//Accepting details of salary and experience
//End of getdata function //Defines virtual functiondisplay
//Displaying details of Staff
//End of display function //End of derived class staff //Creates derived class Student from base class Person //Declares data members under protected section
//Defines getdata1 function
//Accepting details of marks and grade //End of getdata function
//Redefines virtual function display()
//Displaying details of Student
//End of display1 function //End of derived class student //Starts main function
//Creates base class pointer and object //Creates object O1 of Staff //Creates object O2 of Student //Calls accept function //Points to Staff class //Calls display() of Staff class
//Points to Student class //Calls display() of Student class //End of main |
- Here virtual function display is declared in base class.
- Virtual function may or may not be defined in base class. But it has to provide empty definition.
- Thus the output of above program will be :
Output
Enter name
John Mathew
Enter age 25
Enter experience and salary
5 50000
NAME: John Mathew
AGE:25
Experience:5
SALARY:50000
Enter marks and grade
90 A
NAME: John Mathew
AGE:25
MARKS:90
GRADE:A
Introduction
Data Structure can be defined as the group of data elements which provides an efficient way of storing and organising data in the computer so that it can be used efficiently. Some examples of Data Structures are arrays, Linked List, Stack, Queue, etc. Data Structures are widely used in almost every aspect of Computer Science i.e. Operating System, Compiler Design, Artifical intelligence, Graphics and many more.
Data Structures are the main part of many computer science algorithms as they enable the programmers to handle the data in an efficient way. It plays a vitle role in enhancing the performance of a software or a program as the main function of the software is to store and retrieve the user's data as fast as possible
Basic Terminology
Data structures are the building blocks of any program or the software. Choosing the appropriate data structure for a program is the most difficult task for a programmer. Following terminology is used as far as data structures are concerned
Data: Data can be defined as an elementary value or the collection of values, for example, student's name and its id are the data about the student.
Group Items: Data items which have subordinate data items are called Group item, for example, name of a student can have first name and the last name.
Record: Record can be defined as the collection of various data items, for example, if we talk about the student entity, then its name, address, course and marks can be grouped together to form the record for the student.
File: A File is a collection of various records of one type of entity, for example, if there are 60 employees in the class, then there will be 20 records in the related file where each record contains the data about each employee.
Attribute and Entity: An entity represents the class of certain objects. It contains various attributes. Each attribute represents the particular property of that entity.
Field: Field is a single elementary unit of information representing the attribute of an entity.
Need of Data Structures
As applications are getting complexed and amount of data is increasing day by day, there may arrise the following problems:
Processor speed: To handle very large amout of data, high speed processing is required, but as the data is growing day by day to the billions of files per entity, processor may fail to deal with that much amount of data.
Data Search: Consider an inventory size of 106 items in a store, If our application needs to search for a particular item, it needs to traverse 106 items every time, results in slowing down the search process.
Multiple requests: If thousands of users are searching the data simultaneously on a web server, then there are the chances that a very large server can be failed during that process
In order to solve the above problems, data structures are used. Data is organized to form a data structure in such a way that all items are not required to be searched and required data can be searched instantly.
Advantages of Data Structures
Efficiency: Efficiency of a program depends upon the choice of data structures. For example: suppose, we have some data and we need to perform the search for a perticular record. In that case, if we organize our data in an array, we will have to search sequentially element by element. Hence, using array may not be very efficient here. There are better data structures which can make the search process efficient like ordered array, binary search tree or hash tables.
Reusability: Data structures are reusable, i.e. once we have implemented a particular data structure, we can use it at any other place. Implementation of data structures can be compiled into libraries which can be used by different clients.
Abstraction: Data structure is specified by the ADT which provides a level of abstraction. The client program uses the data structure through interface only, without getting into the implementation details.
Data Structure Classification
Linear Data Structures: A data structure is called linear if all of its elements are arranged in the linear order. In linear data structures, the elements are stored in non-hierarchical way where each element has the successors and predecessors except the first and last element.
Types of Linear Data Structures are given below:
Arrays: An array is a collection of similar type of data items and each data item is called an element of the array. The data type of the element may be any valid data type like char, int, float or double.
The elements of array share the same variable name but each one carries a different index number known as subscript. The array can be one dimensional, two dimensional or multidimensional.
The individual elements of the array age are:
Age[0], age[1], age[2], age[3],......... Age[98], age[99].
Linked List: Linked list is a linear data structure which is used to maintain a list in the memory. It can be seen as the collection of nodes stored at non-contiguous memory locations. Each node of the list contains a pointer to its adjacent node.
Stack: Stack is a linear list in which insertion and deletions are allowed only at one end, called top.
A stack is an abstract data type (ADT), can be implemented in most of the programming languages. It is named as stack because it behaves like a real-world stack, for example: - piles of plates or deck of cards etc.
Queue: Queue is a linear list in which elements can be inserted only at one end called rear and deleted only at the other end called front.
It is an abstract data structure, similar to stack. Queue is opened at both end therefore it follows First-In-First-Out (FIFO) methodology for storing the data items.
Non Linear Data Structures: This data structure does not form a sequence i.e. each item or element is connected with two or more other items in a non-linear arrangement. The data elements are not arranged in sequential structure.
Types of Non Linear Data Structures are given below:
Trees: Trees are multilevel data structures with a hierarchical relationship among its elements known as nodes. The bottommost nodes in the herierchy are called leaf node while the topmost node is called root node. Each node contains pointers to point adjacent nodes.
Tree data structure is based on the parent-child relationship among the nodes. Each node in the tree can have more than one children except the leaf nodes whereas each node can have atmost one parent except the root node. Trees can be classfied into many categories which will be discussed later in this tutorial.
Graphs: Graphs can be defined as the pictorial representation of the set of elements (represented by vertices) connected by the links known as edges. A graph is different from tree in the sense that a graph can have cycle while the tree can not have the one.
Operations on data structure
1) Traversing: Every data structure contains the set of data elements. Traversing the data structure means visiting each element of the data structure in order to perform some specific operation like searching or sorting.
Example: If we need to calculate the average of the marks obtained by a student in 6 different subject, we need to traverse the complete array of marks and calculate the total sum, then we will devide that sum by the number of subjects i.e. 6, in order to find the average.
2) Insertion: Insertion can be defined as the process of adding the elements to the data structure at any location.
If the size of data structure is n then we can only insert n-1 data elements into it.
3) Deletion:The process of removing an element from the data structure is called Deletion. We can delete an element from the data structure at any random location.
If we try to delete an element from an empty data structure then underflow occurs.
4) Searching: The process of finding the location of an element within the data structure is called Searching. There are two algorithms to perform searching, Linear Search and Binary Search. We will discuss each one of them later in this tutorial.
5) Sorting: The process of arranging the data structure in a specific order is known as Sorting. There are many algorithms that can be used to perform sorting, for example, insertion sort, selection sort, bubble sort, etc.
6) Merging: When two lists List A and List B of size M and N respectively, of similar type of elements, clubbed or joined to produce the third list, List C of size (M+N), then this process is called merging
Reference Books:
1. Introduction of Computers: Peter Norton, TMH
2. Object Oriented Programming with C++:E. Balagurusamy, TMH
3. Object Oriented Programming in C++: Rajesh K.Shukla, Wiley India
4. Concepts in Computing: Kenneth Hoganson, Jones & Bartlett.
5. Operating Systems – Silberschatz and Galvin - Wiley India
6. Computer Networks: Andrew Tananbaum, PHI
7. Data Base Management Systems, Korth, TMH
8. Cloud Computing, Kumar, Wiley India