OOPS-Paradigm Using C++ Final
OOPS-Paradigm Using C++ Final
Object Oriented
Programing Concept
1.1 INTRODUCTION
Module based programming where the application can be decomposed into modules
and modules can be correlated with classes of high level and real world and reuse of
software where an application can be composed from existing and new modules.
Various most widely used languages which come under the category of OOPs are: C++,
C#, Java, Python, Ruby, et cetera.
1.2 HISTORY OF C++
C++ was initially named ‘C with Classes’. C++ was developed by Bjarne Stroustrup at
AT & T Bell laboratories in Murry Hill, New Jersey, USA, in the early 1980’s.
#include< conio.h>
void main()
{
clrscr ();
int a;
cin>>a;
cout<< a;
getch ();
}
C++ I/O operation uses the stream concept. Stream is the sequence of bytes or flow of
data. It makes the performance fast.
If bytes flow from main memory to device like printer, display screen, or a network
connection, etc, this is called as output operation.
If bytes flow from a device like printer, display screen, or a network connection, etc to
main memory, this is called an input operation.
A variable is a name of memory location. It is used to store data. Its value can be
changed and it can be reused many times. It is a way to represent memory location
through symbol so that it can be easily identified.
Let's see the syntax to declare a variable:
type variable_list;
The example of declaring a variable is given below:
1. int x;
2. float y;
3. char z;
Here, x, y, z are variables and int, float, char are data types.
We can also provide values while declaring the variables as given below:
1. int x=20, b=40; //declaring and initializing 2 variable of integer type
2. float f=10.8;
3. char c='G';
A data type specifies the type of data that a variable can store such as integer,
floating, character etc. Following figure depicts C++ data types.
Figure: C++ Data types
1. Structure: Structure definitions have several formats, all of which include data
members and member functions. To show the formats for structure definitions, let's
look at structure data members first. The first structure format appears frequently in
header files.
struct_name
{
type data_member1;
type data_member2;
type data_membern;
};
The word struct_name is a new data type. Data members may be any type, including
pointers, references, arrays, and other structures whose types do not have the same
name as struct_name. The compiler does not allocate memory with this format
because we define only a type and not a variable.
2. Union: Unions are like structures, but data members overlay (share) memory, and
unions may access members as different types. We use structures and unions in
applications that need user-defined types, such as databases, windows and graphics.
It means, unions have the same formats as structures. Unlike structures, which
reserve separate chunks of memory for each data member, unions allocate only
enough memory to hold the largest data member.
C++ offers a new user-defined data type known as class, which forms the basis of
object-oriented programming. Class acts as a template which defines the data and
functions that are included in an object of a class. Classes are declared using the
keyword “class”. Once a class has been declared, its object can be easily created.
In this declaration, the value of the US is O by default, the value of the UN is 3, India
is 4 and China is 5.
Once an enum type is declared, its variables can be declared using this statement.
These variables countryl, country2 can be assigned any of the values specified in
enum declaration only. For example, consider these statements.
C++ also allows creating special type of enums known as anonymous enums, that is,
enums without using tag name as shown in this statement.
5. The typedef Keyword
C++ provides a typedef feature that allows defining new data type names for existing
data types that may be built-in, derived or user-defined data types. For example,
consider this declaration.
In this declaration, a new name “integer” is given to the data type int. This new name
now can be used to declare integer variables as shown here.
integer i, j, k;
1.7 C++ KEYWORDS
A list of 30 Keywords in C++ Language which are not available in C language are given
below:
● Arithmetic Operators
● Relational Operators
● Logical Operators
● Bitwise Operators
● Assignment Operators
● Unary operators
● Ternary or Conditional Operator
● Special (Misc) Operators
Operators according to unary/binary/ternary collection:
}
In this book, in further chapters either Turbo C++ compiler for Code Block C++
compiler is used.
As written in above example:
#include<iostream.h> includes the standard input output library functions. It provides
cin and cout methods for reading from input and writing to output respectively.
#include includes the console input output library functions.
The getch() function is defined in the conio.h file.
The main() function is the entry point of every program in C++ language. The void
keyword in void main () specifies that it returns no value.
cout<< "Welcome to C++ Programming." is used to print the data "Welcome to C++
Programming." on the console.
getch() The getch() function asks for a single character. Until you press any key, it
blocks the screen.
1.10 FEATURES OF OBJECT-ORIENTED LANGUAGE
Simple
Portable
Compiler based
Object-Oriented
Mid-Level
Recursion Rich-Library
Faster
1. Classes
A class is a logical entity. It is a template or blueprint that defines the
characteristics of an object and describes how the object should look and
behave.
2. Objects
Object is an instance of a class. It is also called a real world entity. It
combines both data and member functions. Objects are the basic run-time
entities in an object-oriented system.
3. Data Abstraction
“Eliminate the Irrelevant, Amplify the Essential”
Abstraction is to focus on the essential and discard the irrelevant. In a way
this does not make sense unless you have a scope. Basically it separates
concept (interface) from implementation.
So, it is true that abstraction is the concept of exposing only the required
essential characteristics and behaviour with respect to a context. It is an
outer layout of process and is ‘design’ like in case of mobile- outer look is-
display screen & keypad to dial a number.
Other examples –
Abstraction shows only important things to the user and hides the internal
details, for example, when we ride a bike, we only know about how to ride
bikes but cannot know about how it works? And also we do not know the
internal functionality of a bike.
4. Encapsulation
"Hiding the Unnecessary"
Encapsulation = Data Hiding + Abstraction.
Encapsulation is hiding the unnecessary.
Data encapsulation is a process. It focuses on the data inside the capsule.
It means hide those things which we want to hide from other people. It
represents the inner layout, in terms of implementation like in the case of
mobile phones, how the keypad buttons and display screen are connected for
performing operations like dial a number.
Other examples:
A teacher does not need to know how a student does her assignment (let
OOPs assignment). She is more interested in the end product.
Let us take an example of a power steering mechanism of a car. Power
steering of a car is a complex system, which internally has lots of
components tightly coupled together, they work synchronously to turn the
car in the desired direction. It even controls the power delivered by the engine
to the steering wheel. But to the external world there is only one interface
available and the rest of the complexity is hidden. Moreover, the steering unit
in itself is complete and independent. It does not affect the functioning of any
other mechanism. Data encapsulation is one of the mechanisms of data
hiding. It an be rectified that encapsulation protect the system, since it hides
stuff that can be vulnerable to malicious attack.
5. Inheritance
"Modeling the Similarity"
Inheritance is a way to reuse once written code again and again. The class
which is inherited is called base class & the class which inherits is called
derived class. Base class in inheritance mechanism is also called parent class
and derived class is also named as child class. So when a derived class
inherits a base class, the derived class can use the functions which are
defined in base class, hence making code reusable.
As similarities often exist in the world.
As shown in image below, one could easily see that there are some
similarities between the two Presidents of the United States, George H.W
Bush (41st President) and George W. Bush (43rd President).
6. Polymorphism
"Same Function, different behavior"
The word “Polymorphism” comes from two Greek words, “many” and “form”.
We can illustrate the idea of polymorphism easily using the scenario where
different animals are asked to “speak”.
It is an object-oriented programming term. The ability to have methods with
the same name, but different content, for related classes. The procedure to
use is determined at run time by the class of the object. For example, related
objects might both have Draw methods. A procedure, passing such an object
as a parameter, can call the Draw method without needing to know what
type of object the parameter is.
The process of representing one thing in multiple forms is known as
Polymorphism.
Example - Suppose if you are in the classroom, at that time you behave like a
student, when you are in market at that time you behave like a customer,
when you at your home at that time you behave like a son or daughter. Here
one person presents in different-different behaviours.
The common example in daily life for polymorphism can be your behavior
which differs at school, work and home. What is common here is behavior, so
it is an interface.
When input is school, behave has one output as you (object) behave in a
certain way at school.
When input is work, behave has another output as you behave differently at
work. When input is home, behavior has yet another output. Three cases
have three different outputs because the input is different, but the interface
(behave) is the same and more importantly there is only one object (you).
Technically polymorphism is one interface different behavior due to different
objects of similar/related type.
Another example of polymorphism in real life, in an exam paper, each
student writes a different answer to the same question (assuming the
question requires a descriptive answer). Here there is only one interface
which is a question in the exam paper. It has different behavior (answers)
due to different objects (students) of similar/related type (human).
7. Data hiding
Data hiding is both a process and a technique. Data in data hiding is private
and non-accessible.
It provides not only less data complexity, but also data protection and
security. It concerns restrictions on terms of access and use. It is used in
classes by making data private.
8. Dynamic binding
It is related to rum-time calls.
Dynamic refers to the linking of a procedure call to the code to be executed in
response to the call. Dynamic binding means that the code associated with a
given procedure call is not known until the time of the call at run-time. It is
associated with polymorphism and inheritance. A function call associated
with a polymorphic reference depends on the dynamic type of that reference.
9. Message passing
In object oriented programs, basically objects communicate with each other.
This processes of communication involves the following basic steps:
1.Creating classes that define objects and their behavior.
2. Creating objects from class definitions.
3. Establishing communication among objects.
1.12 COMPARISON BETWEEN PROCEDURAL PROGRAMMING PARADIGM AND
OBJECT-ORIENTED PROGRAMMING PARADIGM
Declaring a Class
In C++ classes are declared by a keyword class which is written before its name. We
could make as many objects as we want and each object has its own space of fields
and functions in a memory.
Data Members: The variables declared in a class.
Member Functions: The functions declared in a class.
Concepts of an object
The object of a class is also known as its instance and the process of creating an
object is called instantiation of a class. For example car, truck and crane are the three
objects of a class Vehicle; values could be assigned to objects after their declaration.
When class is defined, only the specification for the object is defined; no memory or
storage is allocated.
To use the data and access functions defined in the class, we need to create objects.
An object has: identity (a unique reference), social security number (SSN), employee
number, passport number state, etc called characteristics (variables) and behavior
(methods).
Characteristics such as hungry, sad, running, alive and behavior such as eat, wave,
smile
Interface and implementation of a class
An interface describes the behavior or capabilities of a C++ class without committing
to a particular implementation of that class. Abstract classes are used for creating
interfaces in C++. In other words, an interface is similar to an abstract class with the
following exemptions:
All methods defined in an interface are abstract. Interfaces can contain no
implementation.
Interfaces cannot contain instance variables. However, they can contain public static
final variables (ie. constant class variables)
Interfaces are declared using the "interface" keyword
If an interface is public, it must be contained in a file which has the same name.
Interfaces are implemented by classes using the "implements" keyword.
Implementing Interfaces: A Class can only inherit from one superclass. However, a
class may implement several Interfaces. The interfaces that a class implements are
separated by commas. Any class which implements an interface must provide an
implementation for all methods defined within the interface.
If an abstract class implements an interface, it NEEDS NOT implement all methods
defined in the interface. HOWEVER, each concrete subclass MUST implement the
methods defined in the interface.
Interfaces can inherit method signatures from other interfaces. These abstract classes
should not be confused with data abstraction which is a concept of keeping
implementation details separate from associated data.
Operations on objects
An object is an element (or instance) of a class; objects have the behaviors of their
class. The object is the actual component of programs, while the class specifies how
instances are created and how they behave.
Object-Oriented Terminology says sending a message to an object means asking the
object to execute or invoke one of its methods. Objects of a class are used for
accessing Data Members of Class. In the class-based object-oriented programming
paradigm, "object" refers to a particular instance of a class where the object can be a
combination of variables, functions, and data structures. Accessing a data member
depends solely on the access control of that data member. If it's public, then the data
member can be easily accessed using the direct member access (.) operator with the
object of that class.
If the data member is defined as private or protected, then we cannot access the data
variables directly. Then we will have to create special public member functions to
access, use or initialize the private and protected data members.
It shows that the relationships among different objects can be expressed in several
ways which are described below:
1. Association
2. Aggregation
3. Composition
4. Dependency
5. Abstraction
6. Realization
7. Generalization
Details about different relationships
1. Association
It represents the relationship between two objects. It is also called a "has-a"
relationship that says one class is in some way associated with another class.
0 ... * 0... *
Student Department
Course
2. Aggregation
Aggregation is a specialized form of Association where all objects have their own
lifecycle but there is an ownership like parent and child. Child object can not belong to
another parent object at the same time.
It contains a "has-a" relationship. Also pointer variables are used in it that point to an
object that lives outside the scope of the aggregate class. It is not responsible for
creating/destroying subclasses.
Take an example of Employee and Company:
A single Employee can not belong to multiple Companies, but if we delete the
Company then it doesn’t mean that Employee objects are also destroyed.
Model and Code for the above example is shown below:
Employee Company
3. Composition
Composition is again a specialized form of Aggregation.
It is a strong type of Aggregation.
Here the Parent and Child objects have coincident lifetimes.
Child object does not have its own lifecycle. So, if a parent object gets deleted then all
of its child objects will also be deleted.
It is responsible for creation/destruction of subclasses
Take an example of a relationship between House and its Rooms:
House can contain multiple rooms, there is no independent life for room and any one
room can not belong to two different houses. If we delete the house then the room will
also be automatically deleted.
Model for the above example is shown below:
Room House
4. Dependency
It is also called a using relationship, which means, one class is dependent on another
class. Dependency is defined as a relation between two classes, where one class
depends on another class but another class may or not may depend on the first class.
So, any change in one class can affect the functionality of the other class that depends
on it. For example, we have a Customer class and an Order class.
When we need to save a new order, we need to save it corresponding to a customer.
In order to do so, our Order class will need a reference to the Customer class and save
its data. So in this case, our Order class is dependent on the Customer class.
In the future, if any change is made to the Customer class, it may result in changes to
the Order class. Dependency representation is as below:
Dependency Class ---------------------------- > Dependent Class
5. Abstraction
Abstraction is specifying the framework and hiding the implementation level
information. Concreteness will be built on top of the abstraction. It gives us a
blueprint to follow while implementing the details.
Abstraction reduces the complexity by hiding low level details.
Example: A wire frame model of a car.
6. Realization
Realization relationships means, one class provides a specification and the other class
implements the specification.
Realization is a relationship between the blueprint class and the object containing its
respective implementation level details. This object is said to realize the blueprint
class. In other words, we can understand this as a relationship between the interface
and the implementing class. E.g. a particular model of a car that implements the
blueprint of a car realizes the abstraction.
7. Generalization
This implies an "is a" relationship.
It is also called an "is-a-kind-of" relationship.
One class is derived from another, the base class.
Generalization is implemented as inheritance in C++.
The derived class has more specialization.
It may either override the methods of the base, or add new methods. Examples are a
poodle class derived from a dog class, or a paperback class derived from a book class.
◆◆◆
Chapter 2
Classes and Objects
3.1 INTRODUCTION
▪ Classes are the most important and attractive feature of C++ that leads to Object
Oriented Programming.
▪ A Class is just a blueprint, which declares and defines characteristics and
behavior, namely data members and member functions respectively.
▪ Objects are specific instances of classes and so objects of a class will share its
characteristics and behavior.
▪ Objects are real world entities without which a class has no life. It means, a class
does not exist in reality if no object is created for it.
For example:
A class of birds:
▪ All birds can fly and they all have wings and beaks.
▪ Here flying is a behavior.
▪ Wings and beaks are part of their characteristics.
▪ Also there are many different birds in this class with different names but all have
such behavior and characteristics.
CSE
Class name
number_of_fac
ulty Data Members
number-
of_students
getrecord_facul
Member Functions
ty ()
getrecord_stud
ent ()
showrecord_fa
culty ()
showrecord_st
udent ()
Granny
Objects
smith
Color:
green
Taste:
sour
Display
()
Apple
class
Color:
red
Taste:
sweet
Display
()
// Box specification
ob.height = 4.0;
ob.length = 6.0;
ob.breadth = 3.0;
//volume of box
volume = ob.height * ob.length * ob.breadth;
cout <<"Volume of Box : " << volume <<endl;
return 0;
}
Output:
Volume of Box: 72
Output:
value of C = 3
value of C = 4 output when used concept of static
value of C = 5
Now make a non static type of variable i.e. replace statement static int c=2 with int c=2.
Now output will be:
value of C = 3
value of C = 3 output when variable is not static
value of C = 3
If the f1 () function is called three times then- it is not initialized each time from its value 2 but
will have a previous update.
4) Register:
This storage class is used to store variables in CPU registers instead of RAM. So, the
maximum size of a variable can be equal to the register size.
Prefer this storage for variables that require quick access.
To store the contents of counter variables, registers can be used.
Syntax:
register int var;
If it is not initialized then it stores garbage value.
It has local scope.
5) Mutable:
This is a type of storage class which is not available in C language but is added in C++
as auto, register, static and extern are the storage class in C also.
Sometimes there is a need to modify one or more data members of a class through
const function although it is true that const function can’t update any other value.
This task can be easily performed by using mutable keywords.
Syntax:
mutable int var;
Mutable is mainly useful if in case most of the members should be constant but a few
need updates.
Data members declared as mutable can be modified even though they are the part of
the object declared as const.
//Consider the following example executed in code Blocks IDE: #include
<iostream>
using namespace std;
class M
{
public:
int a;
mutable int b;
M()
{
a = 10;
b = 20;
}
};
int main()
{
const M o1; // o1 is object of class named M but of const type
o1.b= 30;
cout << o1.b;
return 0;
}
Output
30
As o1 is an object of constant type still it can modify values of mutable data members.
So the output of the above program is not 20 for the b variable, it is 30.
In a class, it is possible to make its both data members and member functions of type
static. Following part covers firstly static data members and then static member
functions.
Static Data Members
If a data let int count of a student is created as static then keyword static will precede
it as:
“static int count”
Now for the count variable, only one copy will be created which is accessible for the
whole class.
It is mandatory to define the following statement outside the class for all static data
members.
▪ Use scope resolution to represent type and scope of static data members: let name
I am a student.
o int student :: count ; //c is assigned value zero
or
o int student :: count =1629; //c is assigned value 1629
Static variables are not re-initialized each time as it is called but maintains value
common to the whole class.
//Following example represents use of static data members in a class:
#include<iostream>
using namespace std;
class student
{
static int count; //count variable is of type static and is in private scope
public:
void get ()
{
++count;
}
void show ()
{
cout<<"\n Counting is = "<<count;
}
};
int student :: count; //Mandatory declaration
int main ()
{
student ob1, ob2; //2 objects created for student class
ob1.show (); //count value 0
ob2.show (); //count value 0
ob1.get ();
ob2.get ();
ob1.show (); //count value 2
ob2.show (); //count value 2
return 0;
}
Output
Counting is = 0
Counting is = 0
Counting is = 2
Counting is = 2
}
void show () const
{ rollno = 20; //error
cout<< "Roll no is"<<rollno; }
};
int main ()
{
student ob;
ob.get ();
ob.show ();
return 0;
}
Output: [no output] as Compilation failed due to following error(s).
Compiler error as show () is a const function so cannot change with others.
Error message: assignment of member 'student::rollno' in read-only object
Friend of a class
//Syntax
class classname1
{
private:
……..
public:
……..
friend class classname2;
}; //closing class classname1
class classname2
{
private:
……..
public:
……
classname2 (classname1 object)
{//access classname1 private data using its object
}
};
main function
{
classname1 object1;
classname2 object2;
pass object1 as parameter to object2;
}
As mentioned in syntax written above, classname2 is friend of classname1.
Follow the example written below to clear the concept of friend class.
#include<iostream>
using namespace std;
class A
{
double accno;
public:
A() // constructor of class A
{
accno= 12345;
}
friend class B; //B is another class and is friend of a class
}; //closing class A
class B
{
public:
void show (A ob) //ob is object created for class A
{
cout<<"private details of class A: ";
cout<<ob.accno;
}
};
int main ()
{
A ob1;
B ob2;
ob2. show (ob1); //ob2 (object of class B) will print private details of class A
return 0;
}
Output
private details of class A: 12345
Explanation
First thing to remember is- Do not repeat the keyword friend when writing body of
friend class. It is sufficient to inform the compiler by writing it only inside the class for
which it is a friend.
It means:
friend class B // IT IS WRONG (Friend should not be written here )
{
public:
//body of friend class;
}
But:
friend class B;
Statement is true and compulsory as it is B class declaration and it should be inside A
class because B is Friend of A.
It is clear from above easily demonstrated example that:
▪ A and B are two classes
▪ B is a friend of A because it is declared as a friend inside the scope of A class.
▪ B class has only one public member function named show ().
▪ Show () function is having an argument which is an object of A class. It is mandatory
to pass object of A class in those functions of B which want to access private or
protected members of A class.
▪ Also in main () function, must pass object of A to B when it is going to call that
function which is using A’s private data (data in this case is accno).
Friend Function
A non-member function cannot access the private data of a class because private
access is only allowed to own member functions of a class.
But, in some situations, if an outsider function wants to access private data of a class
then: it is possible with the concept of Friend Function.
A friend function can be declared either in the private or public part of a class without
affecting its meaning.
So, a function can be declared as friend of a class inside the scope of class like:
class A
{
friend void use ( A ob);
}
// It shows that- “A” is a class and “use” is a function which is a friend of A class
called friend function.
Such functions should only be declared inside class. Its definition (body of function)
should be outside the class. Keyword friend precedes function when declared as friend
inside class scope.
Do not repeat keyword friend when defining body of function.
//Syntax
class A
{
……
…….
friend return-type function-name (argument);
};
Now write the body of friend function outside the scope of class.
Do not use scope resolution operator (: :) to define the body of the friend function
because it is friend, not the own function of class.
Define it as
Return-type function-name (argument)
{
Body of friend function with use of private data of A class
}
Return-type of friend function can be void, int, float etc
Arguments passed to function are objects of class A.
It assures class A that only those are my friends which have arguments as objects of
my own class.
//Example using concept of friend function
#include<iostream>
using namespace std;
class A
{
int a, b;
public:
A (int x, int y ) // constructor of class A
{ a=x, b=y; }
Note that private members can be accessed by a friend function using dot operator
like:
ob.a to access a private member named a using object of A passed as argument.
ob.b to access a private member named b in the same manner as a is accessed.
Also in the main () function, the friend function (add) is called by passing an object of
A class. Do not call it as ob.add () because it is not a member function of class A which
is having object ob.
It is possible to create one function as a common friend of two or more classes at the
same time in the same program. Same statement of friend function is declared in all
classes having the same friend function.
One important thing for this scenario is called forward declaration.
According to the forward declaration, to intimate the compiler about more classes that
have common functions as friends, just declare those classes in the beginning of the
program after writing header files for which body will be written later. Such classes are
those who have the same friend function.
Let two classes class A and class B have the same friend function named sum.
If A’s body will be written before and then B’s body then:
Must do forward declaration of B before defining class A as follows:
//Example showing two classes having same friend function:
#include <iostream>
using namespace std;
class B; //forward declaration
class A
{
int a, b;
public:
A()
{
a=10, b=20;
}
friend void sum (A oa, B ob); // oa is object of A class, ob is object of B class
};
class B
{
int c, d;
public:
B()
{
c=30, d=40;
}
friend void sum (A oa, B ob); // oa is object of A class, ob is object of B class
};
void sum (A oa, B ob)
{
int s= oa.a + oa.b + ob.c + ob.d;
cout<<"SUM of Values through friend function : "<<s;
}
int main ()
{
A o1;
B o2;
sum (o1, o2);
return 0;
}
Output
SUM of Values through friend function: 100
i am in local class 2
value given to global variable = 40
It is possible that local classes’ member functions can access variables of enclosing
functions if the variables are static and enum.
Also it is possible that enclosing function can be a member function of a class as
shown below:
#include <iostream>
using namespace std;
class abc
{
public:
void func ( )
{
class loc //loc is local class as defined inside a function
{
public:
void show ( )
{
cout<<"I am local";
}
}; //local class closed here
void show2 ()
{ cout<<" \n Ward no is "<<w; }
};
class contain
{
int dues;
doctor od;
patient op;
ward ow;
public:
void get3 ()
{
od.get ();
op.get1();
ow.get2();
cout<<"\n Enter dues if any";
cin>>dues;
}
void show3 ()
{
od.show ();
op.show1();
ow.show2();
cout<<"\n Pending dues are"<< dues;
}
};
int main ()
{
contain oc;
oc.get3();
oc.show3 ();
return 0;
}
Output:
Enter name of concerned doctor Aman
Enter name of patient XYZ
Enter ward number 2
Enter dues if any 3000
Name of concerned doctor is Aman
Name of patient is XYZ
Ward no is 2
Pending dues are 3000
3.10 BIT FIELDS AND CLASSES
Bit fields: These provide the exact amount of bits required for storage of values.
Actually this concept has a main focus on saving memory space.
It says- if record or information can be settled with the use of bits then avoid
allocating byte for it as byte based data will consume more memory space as
compared to bit based data.. For this, take an example of the status of traffic lights. It
informs either ON or OFF.
So, if a variable would be used for it, then its value will be 1 or 0. It means a total 2
bits are required for such type of storage. One bit for 0 value and another bit for 1
value.
Example:
Use of bit field concept for storing information of a vehicle.
It shows:
If a variable value is in range 0 to 3 then: bit field will be 2.
If a variable value is in range 0 to 7 and exceeding 3 then: bit field will be 3.
//Implementation of bit fields in classes:
#include <iostream>
using namespace std;
#define petrol 1
#define diesel 2
#define two_wheeler 3
#define four_wheeler 4
#define old_model 5
#define new_model 6 // all with #define are macros declarations
class vehicle
{
private:
unsigned fuel : 2;
unsigned type : 3;
unsigned model : 3; // bit field required
public:
vehicle ( )
{
model = old_model;
type = four_wheeler;
fuel = petrol;
}
void show ( )
{
cout<<"Your vehicle details are: \n";
cout<< model << endl << type << endl << fuel;
}
};
int main ( )
{
vehicle ob;
ob.show ( );
return 0;
}
Output
Your vehicle details are:
5
4
1
As shown in above example, macros are declared for various fields relevant to a
vehicle. Here, class name is vehicle which requires hardly one byte to store its
information about fuel (diesel or petrol), type of vehicle (two_wheeler or four) and about
its model (new or old).
Total 2 bits are needed to store information about fuel, total 3 bits for storing
information about type of vehicle and again 3 bits for storing information about model
of vehicle. Here, Colon operator is mandatory to assign bit fields.
The output:
The 5 mean model is old_model.
The 4 mean type is four_wheeler.
1 means it is petrol based.
◆◆◆◆◆
Chapter 3
Console Based Input/Output
C++ programming paradigm provides Input/output standard library with a wide set of
I/O streams that means streams of input flow and of output flow. Input/Output in C+
+ occurs in streams.
Input Source
Output Source
Input Stream
C++ Program
Output Stream
Basically streams act as an intermediary between the programs and the actual IO
devices. It performs operations of file read and write.
2.2 CONSOLE (INPUT/ OUTPUT) STREAM CLASSES
It basically covers istream called input stream and ostream called output stream.
Most important is iOS which is the base of all. The class’s istream and ostream are
bases of iostream (both input and output).
Class ios provides basic support for formatted and unformatted I/O operations.
Class istream provides basic support for formatted and unformatted input operations.
Class ostream provides basic support for formatted and unformatted output
operations.
Following figure illustrates I/O stream classes, also called console stream classes.
ios
istream ostream
iostream
ifstream ostream
fstream
Basic I/O
There are two basic streams which are parts of the I/O stream library and these are cin and
cout.
These are also called:
❖ Stream insertion using << with cin.
❖ Stream extraction using >> with cout.
#include<iostream.h>
#include<conio.h>
class over
{
private:
Int a;
public:
over ( )
{
}
friend istream & operator >> (istream &in, over &ob);
friend ostream & operator << (ostream &out, const over &ob);
}; //class closed
istream & operator >> (istream &in, over &ob)
{
cout << "Enter Value of number”;
in >> ob.a;
return in;
}
ostream & operator << (ostream &out, const over &ob)
{
out << ob.a;
return out;
}
int main()
{
over o1;
cin >> o1;
cout << " \n The Value of number is ";
cout << o1;
return 0;
}
Output
Enter Value of number 30
The Value of number is 30
Advantages of Stream Classes:
▪ Stream classes have good error handling capabilities.
▪ These classes work as an abstraction for the user that means the internal
operation is encapsulated from the user.
▪ These classes are buffered and do not use the memory disk space.
▪ These classes have various functions that make reading or writing a sequence of
bytes are easy for the programmer.
In C++, formatting output is possible in different ways and formatting using ios class
functions and flags is one of the ways for formatting console operations performed on
Input and Output. Also manipulators are helpful for performing formatting of I/O
streams.
There exist various ios functions called ios format functions which are as mentioned
below.
1. width ()
2. fill ()
3. precision ()
4. setf ()
5. unsetf ()
Functions 1 to 3 are used for formatting ios (input/output stream) and functions 4
and 5 are used as formatting flags.
Details about above mentioned format functions of ios:
1. width ()
It defines the width of a field.
Field is what we want to print on the output screen and write with cout.
It is a kind of output function.
It is used as:
cout.width (w); //w = any integer value which will define width of field
The output printed is right-justified in this case that means towards the right side.
Example:
cout.width (7);
cout<<12;
Output:
2. Fill ()
Also known as filling and padding.
The width function adds white spaces as decided by the width of the field.
Fill () is used to fill the unused positions by any desired character.
It is also a kind of output function.
It is used as:
cout.fill (ch);
//ch is any character used to fill white spaces added by width function
Example:
cout.fill (‘*’);
cout.width (7);
cout<<12;
Output:
* * * * * 1 2
3. Precision ()
As standard for printing floating values are six digits after the decimal point. But, with
the help of precision () function, we can specify the number of digits to be displayed
after the decimal point when dealing with float values.
It is used as:
cout.precision (x);
Example:
cout.precision (3);
cout<<1.2455555;
Output:
1.25
4. Setf ()
It is a member function of ios class and known as set flags.
It is used as:
cout.setf (argu1, argu2)
//argu1 and argu2 are used for setf () function as its arguments.
It is same as following for width ():
cout.setf (ios::left, ios::adjustfield)
Argu1: formatting flag existing in ios and
Argu2 is a bit field which specifies the group to which the formatting flag belongs.
Make sure that argu1 should be one of the group members of the argu2.
It is used in following situations like:
As we know width () is right justified but what to do if the user wants to print output
as left justified.
So, in such cases- setf () is helpful.
Example:
cout.fill (‘*’);
cout.setf (ios::left, ios::adjustfield);
cout.width (7);
cout<<12;
Output:
1 2 * * * * *
S. Argu1 Meaning
N (flag)
o.
1 ios::show Use base indication on output
base
2 ios::show Print + before positive numbers
pos
3 ios::show Show trailing decimal point and zeroes
point
4 ios::uppe Use uppercase letters
rcase
5 ios::skip Skip white spaces on input
ws
6 ios::unit Flush all streams after insertion
buf
7 ios::stdio Flush stdout and stderr after insertion
Table: Flags without bit-fields
4. Setw
It is a set field width manipulator.
It is a kind of manipulator which is used to set the width that a particular value will
consume. It is a parameterized manipulator but used like an output manipulator.
The total spaces consumed by a variable are equal to the argument value passed to setw ()
like: setw (10) has total spaces =10.
So, if the value is of only 2 characters then the remaining 8 spaces will be blank spaces
called white spaces. The white spaces will be from the left side as it is right justified so
contents i.e. value will consume spaces from the right side. It is also an output
manipulator and use of the header file “iomanip” is mandatory for it.
Example:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int a=10, b=786;
cout<< setw (5) << a << setw (5) << b;
return 0;
}
Output
1 0 7 8 6
As shown above, three blank spaces also called white spaces before the value of a (i.e.
10) are printed and two white spaces before the value of b (i.e. 786) is printed. The
reason is: a itself is of 2 characters but b is of three characters.so:
For variable a, blank spaces are 5 minus 2 equals 3.
For variable c, blank spaces are 5 minus 3 equals 2.
5. setfill
It is a parameterized manipulator but used like an output manipulator.
It is a set fill manipulator used to fill empty/unused white spaces that were added to a value
by using setw () manipulator. It allows users to use any symbol to fill unused spaces.
The argument value passed to setfill() should be any symbol.
It is used in combination with setw () as it is having an impact on setw ().
Its syntax is: setfill (char c).
Example 1: Use same symbol to fill all empty spaces in whole program
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int a=10, b=786;
cout<<setfill (‘+') << setw (5) << a << setw (5) << b;
return 0;
}
Output
+ + + 1 0 + + 7 8 6
6. Setprecision
It is also a parameterized manipulator but used like an output manipulator.
It is used to control the number of decimal digits of a float value which will be
displayed on the output screen.
As standard for printing floating values are five digits after the decimal point. But,
with the help of setprecision () manipulator, we can specify the number of digits to be
displayed after the decimal point when dealing with float values.
Example:
#include <iostream>
#include <iomanip> //mandatory
using namespace std;
int main()
{
float a=10, b=3;
float c=a/b;
cout<<setprecision (3) << c;
return 0;
}
Output:
3.33
As shown above, instead of output 3.33333,
The round figure after decimal is only 2 digits because the argument value passed to
setprecision is 3.
7. Ends
Full name of this manipulator is end of string. It inserts null character at the end of a string
to show its termination. It is also one of the important output manipulators.
There is one difference as it succeeds the string on which i.e. applied after string is printed as
shown below:
Example:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int a=10;
cout<<a << ends;
return 0;
}
Output
10
Ends written after “a“means string is terminated here.
8. Ws
Full name of this manipulator is white space.
It is an input manipulator.
It is used to ignore the leading white spaces that are succeeding the first field.
So, it will print the typed or input string till the first blank space i.e. printing on the output
screen till any white (empty/blank) space comes.
Example:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
char pwd [15];
cout<< "Enter password::” ;
cin>> ws >> pwd;
cout << endl << "After applying ws on pwd – output is ----- "<< pwd;
return 0;
}
Output:
Enter password:: KEVI @ 123
After applying ws on pwd – output is ----- KEVI
As shown in above example- first white space came after KEVI and before @.
So, the manipulator has ignored all characters leading after this white space.
9. Flush
▪ It is an output manipulator used as a flush cleaner buffer.
▪ Its behaviour as a manipulator is equivalent to calling OS's member function flush.
▪ The flush member function is used to cause the stream associated with the output
to be completely emptied.
▪ The argument of flush takes no input parameters whenever it is invoked.
▪ For input on the screen, this is not necessary because all output is flushed
automatically. However, in the case of a disk file being copied to another, it has to
flush the output buffer prior to rewind the output file for continued use.
▪ The function flush ( ) does not have anything to do with flushing the input buffer.
Used as:
cout.flush ( );
//Example using flush member function
//it is executed in online g++ compiler of C++
#include <iostream>
using namespace std;
int main()
{
cout <<" Hello in the World of C++ \n";
cout << " This is my loving subject \n";
cout . flush ( ) ;
return 0;
}
Output
Hello in the World of C++
This is my loving subject
10. Setiosflags
The setiosflags manipulator function is used to control different input and output
settings. The I/O stream maintains a collection of flag bits.
The setiosflags manipulator performs the same function as the setf function.
The flags represented by the set bits in f are set.
The general syntax of the setiosflags is: setiosflags ( long h)
◆◆◆◆◆
Chapter 4
Constructors & Destructors
5.1 CONSTRUCTORS
5.2 DESTRUCTOR
A destructor is a special member function of a class which destroys the object as soon
as the scope of object ends.
The destructor is called automatically by the compiler when the object goes out of
scope.
The syntax for destructor is same as that for the constructor, the class name is used
for the name of destructor; with a tilde~ sign as prefix to it (add ~ before destructor).
Destructors will never have any arguments.
As mentioned below, destructor is created inside the class:
class A
{
public:
~A( );
};
The following restrictions apply to both constructors and destructors:
▪ Constructors and destructors do not have return types nor can they return values.
▪ References and pointers cannot be used on constructors and destructors because
their addresses cannot be taken.
▪ Constructors and destructors cannot be declared static, const, or volatile.
▪ Unions cannot contain class objects that have constructors or destructors.
1. Default Constructor
Default constructor is the constructor which doesn't take any argument. It has no
parameter.
Syntax:
class_name ()
{
Constructor Definition
};
//Example illustrating use of default constructor :
#include <iostream>
using namespace std;
class A
{
int rno;
public:
A( ) // A ( ) is default constructor as having no argument in parenthesis
{
rno=10;
cout<<rno;
}
};
int main()
{
A ob;
return 0;
}
Output
10
In this case, when object ob is created the constructor is called which initializes its
data members (rno with value 10).
If in case, a default constructor is not defined by programmer then compiler provides
default constructor implicitly.
//Another example illustrating use of default constructor:
#include <iostream>
using namespace std;
class A
{
public:
int rno;
};
int main()
{
A ob;
cout << ob.rno;
return 0;
}
Output
0
In this case, default constructor provided by the compiler will be called which will
initialize the object data members to default value that will be 0 in this case.
2. Parameterized Constructor
These are the constructors with parameter like: A (int i, int j) .
A is name of constructor, i and j are two variables of integer data type.
//Class with parameterized constructor:
class A //A is class name
{
public:
A (int i , int j ) // A is parameterized constructor
}
3. Copy Constructor
In C++, one constructor can be copied into another one. Basically, it is used to copy
one object into other for a class. It creates a copy of an already existing object. It
occurs for a class type.
It is usually of the form A ( A& ), where A is the class name.
The compiler provides a default Copy Constructor to all the classes.
Syntax:
Classname( const classname & objectname )
{
....
}
In this process, pass reference of object as an argument to constructor.
Let con is name of class, so same is name of constructor. Then, use concept of copy
constructor as:
{
con ( con& ob1)
{ A = ob1. A; }
}
Inside main () ,
con o1;
con o2 ( o1 ) ; // copy constructor concept.
As mentioned above, reference operator is used which is helping to pass value from
one object to another.
//C++ example illustrating use of copy constructor
#include <iostream>
using namespace std;
class con
{
int a;
public:
con (int x )
{
a = x;
cout<<" Value before copying "<<a;
}
con ( con & ob1)
{
a = ob1. a;
cout<<"\n Value after copying "<<a;
}
};
int main ()
{
con o1 (5);
con o2 ( o1 );
return 0;
}
Output
Value before copying 5
Value after copying 5
#include<iostream>
using namespace std;
class con
{
int a, b; // Variable Declaration
public:
con() //Constructor without parameters
{ // Assign Values in Constructor
a = 50;
b = 60;
cout << "\nIn Constructor without parameters";
}
con(int x, int y) //Constructor with parameters
{ // Assign Values In Constructor
a = x;
b = y;
cout << "\nIn Constructor with parameters";
}
void display()
{ cout << "\nValues are: " << a << "\t" << b;
}
};
int main()
{
con Ob1;
Ob1.display();
public:
con ( )
{
p = new int;
*p = 20;
}
void show ()
{
cout<< "The value of pointer variable is "<< *p;
}
};
int main ( )
{
con o1;
o1. show ( );
return 0;
}
Output
The value of pointer variable is 20
As shown in above example, a class named con has pointer type variable declared in
it. Also using new operator, memory is allocated to it inside the code of constructor
dynamically.
Value by Construcor 10
Value by Construcor 20
Here, class name is ABC and ob1, ob2 are its objects.
According to statement:
ABC ob2= 20
Value 20 is initialized to object ob2 of ABC but the point to notice here is, ob2 is object
of type base but 20 is of type integer. So, question is how it can be done. Such
conversion is called constructor conversion i.e. implicit conversion. To avoid this, use
explicit keyword with constructor as:
explicit ABC (int x)
So, the explicit constructor is helpful to control unwanted implicit type conversions.
Use it within a class declaration.
ABC ob = 20; is legal and is same as ABC ob1 = con (20).
If explicit keyword is used then assigning a value like ABC ob = 20 is illegal but
passing value explicitly through con ob = con (20) is legal.
◆◆◆◆◆
Chapter 5
Operator Overloading
& Type Conversion
6.1 OPERATOR OVERLOADING
It is one of the features of C++.
As the term overload means use one thing more than once.
Same is case of operator overloading which says:
Pick an operator (Let plus (+) operator and then overload it by performing different
operations on it as following:
▪ + can be used for adding two integers as 10 + 20
▪ + can be used to add two strings as “Hello” + “world” called concatenation
operation.
▪ + can be used to add two float values as 5.6 + 4.4
Yet it is not completely operator overloading in C++.
So, operator overloading of + operator is complete with following:
▪ + can be used to add two objects as obj1 + obj2. These objects should refer to a
class.
So, its Syntax is:
Return-type class-name: operator operator-symbol ( arguments)
{
}
● ! (NOT)
● && (AND)
Logical operators
● || (OR)
● += (addition-assignment)
● -= (subtraction-assignment)
● *= (multiplication-assignment)
● /= (division-assignment)
Compound assignment
● %= (modulus-assignment)
operators
● &= (AND-assignment)
● |= (OR-assignment)
● ^= (XOR-assignment)
● <<= (shift-left-assignment)
● >>= (shift-right-assignment)
● ++ (increment) Increment and decrement
● -- (decrement) operators
● new (allocate memory for object)
● new[ ] (allocate memory for array)
Memory management operators
● delete (deallocate memory for object)
● delete[ ] (deallocate memory for array)
● , Comma operator
● -> ( ) Member access operators
● ->* ( )
● () Function call operator
● [] Subscript operator
Following are some important rules which a programmer should follow while
overloading an operator:
▪ Only existing operators can be overloaded.
▪ Overloaded operators follow the syntax rules of the original operators. They cannot
be overridden.
▪ The overloaded operator must have at least one operand that is of user defined
type.
▪ We cannot change the basic meaning of an operator. It means, we cannot redefine
the plus (+) operator to subtract one value from the other.
▪ There are some operators that cannot be overloaded like size of operator (sizeof),
membership operator (.), pointer to member operator(.*), scope resolution
operator(::), conditional operators(?:) etc.
▪ We cannot use “friend” function to overload certain operators. However, member
function can be used to overload them. Friend Functions cannot be used with
assignment operator (=), function call operator (( )), subscripting operator([n]), class
member access operator (->) etc.
▪ When using binary operators overloading, the left hand operand must be an object
of the relevant class.
▪ Binary arithmetic operators such as +,-,* and / must explicitly return a value. They
must not attempt to change their own arguments.
It is easy to know about operator overloading from above mentioned program that
when two objects are added then automatically overloading code written inside the
class will be called. It is mandatory that it should contain “operator” keyword.
Another way to overload a binary operator in C++.
//C++ Program to overload + operator using member function method
#include <iostream>
using namespace std;
class complexno
{
int real, imag;
public:
complexno ( )
{ }
complexno (int x, int y)
{
real = x;
imag = y;
}
void show ()
{
cout<< real << " + i " <<imag <<endl;
}
complexno operator + (complexno c)
{
complexno c1;
c1. real = real + c . real;
c1. imag = imag + c. imag;
return (c1);
}
};
int main ( )
{
complexno o1 (10, 20);
cout<<"In a + i b form - Object o1 is : ";
o1. show ();
complexno o2 (15, 25);
cout<<"In a + i b form - Object o2 is : ";
o2.show ();
complexno o3 ;
o3 = o1 + o2;
cout<<"In a + i b form - SUM OF TWO COMPLEX NUMBERS IS : ";
o3. show();
return 0;
}
Output
In a + i b form - Object o1 is : 10 + i 20
In a + i b form - Object o2 is : 15 + i 25
In a + i b form - SUM OF TWO COMPLEX NUMBERS IS : 25 + i 45
In above program code, o3 = o1 + o2 will work as:
When this statement will execute then the code of operator function written in class
public section will be called. Object o2 which is on right part of operator symbol will be
copied into object ob which is created as argument in ‘complexno operator +
(complexno c)’ function.
Here o1 + o2 means calculate, execute complete body of operator + ( ) function.
As its body is:
complexno operator + (complexno c)
{
complexno c1;
c1. real = real + c . real;
c1. imag = imag + c. imag;
return (c1);
}
Basically object o2 is copied into object c at the time of execution.
‘c1. real = real + c . real ’ statement will find sum of real part of o1 and o2.
‘c1. imag = imag + c. imag’ will find sum of imaginary part of o1 and o2.
Real part is first argument and imaginary part is second argument.
Result to o3 is finally provided by c1 as return (c1) statement is doing.
Same like + operator, other arithmetic operators can also be overloaded as written
below.
o3 = o1 – o2;
o3 = o1 * o2;
o3 = o1 / o2;
o3 = o1 % o2;
Use friend function to overload bnary + operator:
The syntax is-
friend void operator + (complexno c, complexno d);
Above statement should be written in class body. When using friend function concept
for overloading binary operator then we need two arguments which are of object type.
First argument will help to pick values comes on left side of + and second argument
will pick value on right side of +.
T is one more object which will accept output after addition.
So, t.real will print addition of two real values of two objects and t.imag will print
addition of two imaginary values.
In main () function, two objects are created and then after passing values to both, they
are called to do binary addition.
Ultimately the code of + function will be called which is created with the help of friend
function concept.
There will be matching like- o1 with values 10, 20 will go to object c of + function and
o2 with values 15, 25 will go to object d of + function which is second argument of the
statement: void operator + (complexno c, complexno d). Finally we will get addition of
both.
This method is also an easy method to use for overloading unary, binary and other
operators which comes under the list of overloaded operators.
Following example is using one more method to overload an operator in C++.
//C++ Program to overload + operator using friend function method
#include <iostream>
using namespace std;
class complexno
{
int real, imag;
public:
complexno ( )
{ }
complexno (int x, int y)
{
real = x;
imag = y;
}
void show ()
{
cout<< real << " + i " <<imag <<endl;
}
friend void operator + (complexno c, complexno d);
}; //class closes here
void operator + (complexno c, complexno d)
{
complexno t;
t.real = c.real + d.real;
t.imag = c.imag + d.imag;
cout<<" Sum of Real Values "<<t.real;
cout<<"\n Sum of Imaginary Values "<<t.imag;
}
int main ( )
{ complexno o1 (10, 20);
complexno o2 (15, 25);
o1 + o2;
return 0;
}
Output:
Sum of Real Values 25
Sum of Imaginary Values45
In above program, friend keyword is written to allow friend function use for operator
overloading. Same program can be executed with the concept of member function.
Same code can be used to overload other assignment operators by updating operator
at required places.
In programming, type conversion (type casting) or type coercion are different ways
of changing an entity of one data type into another.
For example: conversion of an integer value to floating value.
If conversion is performed itself then it is called implicit conversion as mentioned
below.
◆◆◆◆◆
Chapter 6
Inheritance
7.1 INTRODUCTION
Example: "She had inherited the fair complexion from her mother".
public protected
private
1 public public protecte not
d acces
sible
2 protected protecte protecte not
d d acces
sible
3 private private private not
acces
sible
1. Single Inheritance
One base class and one derive class.
D
Single Inheritance
2. Multilevel Inheritance B
D3
Multilevel Inheritance
In above diagram, inheritance is at many levels.
At level 1- D1 is derive of base B.
At level 2- D2 is derive of base D1.
At level 3- D is derive of base D2.
3. Multiple Inheritance
Many base classes of one derive class.
Multiple base classes at same level forms multiple inheritance
B1 B2 B3
D
Multiple Inheritance
Here, B1, B2 and B3 are three base classes of one derive class D.
4. Hierarchical Inheritance
It is tree shaped inheritance with more derive classes from one base class.
D1 D2 D3
Hierarchical Inheritance
5. Hybrid Inheritance:
It is combination of more than one type of inheritance. Combination is preferred from
above mentioned inheritance types.
Hierarchical Inheritance + Multiple Inheritance = Hybrid Inheritance
Multiple Inheritance + Multilevel Inheritance = Hybrid Inheritance
Hierarchical Inheritance + Multilevel Inheritance = Hybrid Inheritance
B1 B2
Hybrid Inheritance
B
D1 D2
C
Figure showing ambiguity in class ‘C’
Here, C is derived from two classes D1 and D2 directly. Classes D1 and D2 both have
common base class (B class).
It means there are two paths via which data of B class reaches to C and the data is
same (called ambiguous data or duplicate data).
If inheritance is via multipath (more than one path) then one base class will be
inherited by different derive classes. So it means, derive classes will have common
copy of base (copy of B class). If these derive classes (D1, D2) have further one derive
class (same as multiple inheritance) then duplicate copy of root base class (which was
common) will be generated.
Following figure elaborates same concept in more detail.
B
In above example, output of two classes inherited in one common class with same
named fuction is printed without any error.
Following statements:
obj. A :: show() and
obj. B :: show() have removed ambiguity.
Another example to remove ambiguity in multipath inheritance:
//Example using scope resolution operator to remove ambiguity.
#include <iostream>
using namespace std;
class B
{ public: void get ( )
int a =100;
};
class D1 : public B
{ };
class D2 : public B
{ };
class C : public D1, public D2
{ };
int main()
{
C ob;
cout<< "\n A : "<< ob.D1 :: a; //no ambiguous value
return 0;
}
Output: A 100
According to above example, class C has two copies of “a” with same value 100. It is
ambiguity.
Here, during call of such members, scope resolution operator has removed ambiguous
problem.
Another example to remove ambiguity in multipath inheritance:
// Example using scope resolution operator to remove ambiguity.
#include <iostream>
using namespace std;
class B
{ int a;
public:
void get ()
{ a = 50;
cout<<"Value is "<<a;
}
};
class D1 : public B
{ //here get () function copy is inherited
};
class D2 : public B
{ //here get () function copy is inherited
};
class C : public D1, public D2
{ //here two get () copies are inherited
};
int main()
{ C ob;
ob. D1 :: get ( ); // It means get () of D1 should be called
return 0;
}
Output
Value is 50
D1 D2
C
Figure: Virtual base class concept
The code in following examples has removed ambiguity by making base class as
virtual class.
// Example using virtual base class concept to remove C++ ambiguity
#include <iostream>
using namespace std;
class B
{ public:
int a =100;
};
class D1 : virtual public B
{ };
class D2 : virtual public B
{ };
class C : public D1, public D2
{ };
int main()
{
C ob;
cout<< "\n A : "<< ob.a;
return 0;
}
Output:
A 100
In above example, class D1 has a copy of “a” with value 100.
Class D2 also has a copy of “a” with value 100.
Now, class C has two copies of “a” with same value 100.
By making base class B as virtual, this ambiguity has been easily removed and so, in
output only one copy of “a” is printed.
Another example using virtual base class concept:
// Example using virtual base class concept to remove C++ ambiguity.
#include <iostream>
{ public: int a; };
int main()
C ob;
return 0;
Output :
A : 50
In this example, C has only one copy of B therefore statement (2) will overwrite the
value of a, given at statement (1). So, value 50 is printed.
};
}
Output
Inside base class
Inside sub class
Order of constructor call in Multiple Inheritance
As in multiple inheritance, bases classes are more than one. So,
The base class’s constructors are called in their order of inheritance and then the
derived class’s constructor is called.
//Example expressing order of constructors call in Multiple Inheritance:
#include <iostream>
using namespace std;
// first base class
class B1
{
public:
// first base class's Constructor
B1()
{ cout << "Inside first base class" << endl; }
};
// second base class
class B2
{
public:
// second base class's Constructor
B2()
{ cout << "Inside second base class" << endl; }
};
// C class inherits B1 and B2
class C : public B1, public B2
{
public:
// child class's Constructor
C ()
{ cout << "Inside child class" << endl; }
};
// main function
int main()
{ // creating object of class Child
C ob;
return 0;
}
Output
Inside first base class
Inside second base class
◆◆◆◆◆
Chapter 7
Pointers and Dynamic Memory
Management
4.1 INTRODUCTION
During programming, when a user initializes a variable (let: int a=2 ;), then
automatically a free memory address is assigned to the variable.
So the result is: variable “a” with value 2 is stored at that memory address.
In this scenario, we don’t need to worry about what specific memory address is
assigned. All is performed by compiler. But it is without pointers. Such space is
allocated in static way.
On other side, pointers have supported memory management dynamically which
means no memory space wastage.
Definition of Pointers
p1 = &b;
// incorrect since int pointer cannot point to the address of a double variable
p2=&a;
// incorrect since float pointer cannot point to the address of an int variable
getch( );
}
Output:
Compilation failed due to following error(s).
p1 = &b;
cannot convert 'int*' to 'float*' in assignment
p2=&a;
4.6 ACCESSING DATA THROUGH POINTERS
Use Dereferencing pointers for this purpose.
It helps to retrieve the data of the address a pointer variable is pointing to.
Another example using pointers:
#include <iostream>
using namespace std;
int main()
{
int a = 5;
cout<<&a<<endl; // prints address of value (0012FF7C)
cout<<a<<endl; // prints contents of value (5)
int *p;
p = &a;
// initialize pointer p with address of variable a means p “points to” a
cout << p << endl ;
// prints address held in p, which is same as &a (0012FF7C)
cout << *p ; // dereference p (get the value that p is pointing to- (5))
return 0;
}
Output
0x7ffd717c28ec
5
0x7ffd717c28ec
5
C malloc ()
It allocated the memory space of given size. Also it returns the pointer to beginning of
the block.
It doesn’t initialize the allocated memory.
C calloc()
The name calloc stands for "contiguous allocation".
The only difference between malloc() and calloc() is that:
malloc() allocates single block of memory whereas calloc() allocates multiple blocks of
memory each of same size and sets all bytes to zero.
Syntax of calloc()
ptr = (cast-type*)calloc(n, element-size);
This statement will allocate contiguous space in memory for an array of n elements.
For example:
ptr = (float*) calloc(25, sizeof(float));
This statement allocates contiguous space in memory for an array of 25 elements each
of size of float, i.e, 4 bytes.
C free()
Dynamically allocated memory created with either calloc() or malloc() doesn't get freed
on its own. You must explicitly use free() to release the space.
syntax of free()
free(ptr);
This statement frees the space allocated in the memory pointed by ptr.
C realloc()
If the previously allocated memory is insufficient or more than required, you can
change the previously allocated memory size using realloc().
Syntax of realloc()
ptr = realloc(ptr, newsize);
Here, ptr is reallocated with size of newsize.
No doubt, pointers are flexible. Also memory management through pointers use is
more beneficial than static allocation. Yet following are some problems which arise
with the use of pointers.
1. Null pointer
2. Memory Leak
3. Memory Corruption
4. Dangling Pointer
5. Wild Pointer
1. Null Pointer: It is a kind of problem which arises when a pointer variable is declared in a
program but not any address is assigned to it.
Solution to this problem:
Either assign NULL to such pointer variable as:
int *p;
P = NULL;
Or
Erase such pointer variable which is not used later also.
When NULL is assigned to pointer variable then it gives output zero (0).
3. Memory Corruption: This problem occurs because of different reasons like, if contents of
a memory location are accidentally changed.
Mostly memory corruption occurs because of programming errors. If in a program, data is
written to wrong memory location then also it becomes memory corruption. It means
going against memory safety.
Some other reasons of memory corruption are as following:
▪ Attempting to free memory already freed.
▪ Freeing memory that was not allocated.
▪ Attempting to read/write memory already freed.
▪ Attempting to read/write to memory which was never allocated.
▪ Memory allocation error.
▪ Reading/writing to memory out of the bounds of a dynamically allocated array
{
int x;
p = & x; // Now p is a dangling pointer
}
5. Wild Pointer: It is also called uninitialized pointer as wild pointer points to illogical
memory locations. So, many times, wild pointer caused a program to behave badly.
These are called unbound pointers.
Case 1: Wild Pointer
int main()
{
int *p; //p is wild pointer
}
A pointer is a data object which contains the address of some other data object So, if x
contains the address of y then programmers say: "x points to y."
Dynamic memory is allocated using operator new. New is an operator.
New operator:
New is followed by a data type specifier (int, float, chat etc) and if more than one
element is required, the number of these are mentioned within brackets [].
It returns a pointer to the beginning of the new block of memory allocated.
Its syntax is:
pointer = new type; ------------------------- Expression 1
Or
pointer = new type [ number-of-elements]; ------------------------- Expression 2
Expression 1 is used to allocate memory to contain one single element of type type.
Expression 2 is used to allocate a block (an array) of elements of type type, where
number-of-elementsis an integer value representing the amount of these. For example:
int * p;
p = new int [3];
In this case, the system dynamically allocates space for three elements of type int and
returns a pointer to the first element of the sequence,
p
Delete Operator:
Once the memory is allocated using new operator, it should be released back to the
operating system.
If the program uses a large amount of memory using new, system may crash because
there will be no memory available for the operating system.
The following expression returns memory back to the operating system.
delete [] ptr;
The brackets [] indicates the array has been deleted. If you need to delete a single
object then, you don't need to use brackets.
delete ptr;
So, to safely use pointers, releasing dynamic memory is also an important step. It is
possible with proper use of delete which is also an operator.
It is used after using completely new and before exiting from program as following:
int * p, p1;
p= new int [50];
p1= new int;
delete [ ] p;
delete p1;
//Example: Write a C++ program to store GPA of n number of students and display it
where n is the number of students entered by user. Use memory management operaots
for same.
#include <iostream>
using namespace std;
class Test
{
private:
int num;
float *ptr;
public:
Test()
{
cout << "Enter total number of students: ";
cin >> num;
ptr = new float[num];
cout<< "Enter GPA of students." << endl;
for (int i = 0; i < num; ++i)
{
cout << "Student" << i + 1 << ": ";
cin >> *(ptr + i);
}
}
~Test() {
delete[] ptr;
}
void Display()
{
cout<< "\nDisplaying GPA of students." << endl;
for (int i = 0; i < num; ++i) {
cout << "Student" << i+1 << " :" << *(ptr + i) << endl;
}
}
};
int main() {
Test ob;
ob.Display();
return 0;
}
Output
Enter total number of students: 4
Enter GPA of students.
Student1: 2.3
Student2: 3.8
Student3: 3.9
Student4: 2.7
In above program example, when the object ob is created, the constructor is called
which allocates the memory for num floating-point data. When the object is destroyed,
i.e, when the object goes out of scope, destructor is automatically called.
~Test() {
delete[] ptr;
}
This destructor executes delete [ ] ptr; and returns memory back to the operating
system. This is dynamic memory management.
◆◆◆◆◆
Chapter 8
Virtual Functions &
Polymorphism
8.1 POLYMORPHISM
It is one of the important and strongest features of Object Oriented Programming
(OOP).
Basically polymorphism means poly + morph = one name in many forms.
Morph is one thing and Poly means many forms.
Types of Polymorphism:
It has two types.
▪ Compile time Polymorphism
▪ Run time Polymorphism
Compile time polymorphism is also called Early Binding or Static Binding.
On other side, run time Polymorphism is also named as Late Binding or Dynamic
Binding. Further types of Polymorphism are neatly structured in following diagram.
Polymorphism
Compile-Time Run-Time
(Early Binding) (Late Binding)
class D: public B
{
public:
void show ()
{ cout<< "derived class "; }
};
int main ( )
{
B * p; //pointer object of base class
B ob1;
D ob2;
In above example: the question is why output of derived class is not printed when
reference of derived is passed to pointer object. The reason is: it doesn’t matter for
pointer object that which contents are passed to it but it matters that for which class
it is declared. So, base class output always overrides derived class output when
function name is same (requirement of polymorphism). So, the solution is: make
function virtual which is overriding another function. The concept of virtual function
can be implemented at Run-Time called Late Binding in C++.
Late Binding in C++
In the case of late binding, the compiler matches the function call with the correct
function body at runtime.
It is also known as Dynamic Binding or Runtime Binding.
In it, the compiler identifies the type of object at runtime and then matches the
function call with the correct function definition. So, it prints body of function whose
reference is passed to pointer object as virtual keyword means do not consider in
reality. As it is clear- by default early binding takes place. But if we declare base class
function as virtual then the problem of previous example (example of early binding)
can be solved.
8.3 VIRTUAL FUNCTION
▪ A virtual function is a member function of the base class which is overridden in
the derived class. The compiler performs late binding on this function.
▪ To make a function virtual, we write the keyword virtual before the function
definition.
▪ Virtual means not in reality but in effect. So, if a function is of type virtual then its
body usually does not print but it is defined as per concept of polymorphism.
▪ It is Run Time Polymorphism. So, Late Binding is allowed when concept of virtual
function is used in a program.
▪ It uses keyword virtual preceding the function to which programmer wants to make
of virtual effect. It means, a virtual function doesn’t exist in reality but it has an
effect in a program.
▪ It uses two basic concepts- one is pointer of base class which means object of base
class is created as pointer type and another is same named function in base and
derived class. Here, base class function is declared as virtual so that it will not
override the body of derived class function which is also of same name.
▪ It is also a member function declared within base class and is re-defined by
derived class.
The code in following example makes the concept of virtual function clear:
// Late Binding in C++ Program
#include <iostream>
using namespace std;
class Animals
{
public:
virtual void sound()
{ cout << "This is parent class" << endl; }
};
class Dogs : public Animals
{
public:
void sound()
{ cout << "Dogs bark" << endl; }
};
int main()
{
Animals *a;
Dogs d;
a= &d;
a -> sound();
return 0;
}
Output:
Dogs bark
Explanation of above example:
Since the function sound () of the base class is made virtual, the compiler now
performs late binding for this function.
Now, the function call will be matched to the function definition at runtime. Since the
compiler now identifies pointer “a” as referring to the object 'd' of the derived class
“Dogs”, it will call the sound() function of the class Dogs (derived class with output-
Dogs bark).
Another example using Virtual Function (Late Binding):
// Virtual Function concept is used
#include <iostream>
using namespace std;
class B
{
public:
virtual void show () // virtual function
{ cout<< "Base class \n"; }
};
class D: public B
{
public:
void show ()
{ cout<< "Derived class "; }
};
int main ( )
{
B * p; //pointer object of base class
B ob1;
D ob2;
p = & ob1; // address of base class provided to pointer object
p -> show ();
p = & ob2; // address of derived class provided to pointer object
p -> show ();
return 0;
}
Output
Base class
Derived class
Explanation of above example:
In above example, base class function is of type virtual. So, when the reference of
derived class is passed to base class pointers object then:
Because of virtual type function- base class show () has no real existence. It means, it
is not overriding now derived class show () output. So,
p = & ob2;
p -> show ();
It will print output: “derived class” instead of “base class”.
int main()
{
D *d = new D();
B *b = d;
delete b;
return 0;
}
Output:
derived destruction of objects
base destruction of objects
Now, by making base class destructor as virtual, the destructors of both derived and
base class are called.
◆◆◆◆◆
Chapter 9
Exception Handling
9.1 TRADITIONAL ERROR HANDLING
◆◆◆◆◆
Chapter 10
Templates and Generic
Programming
10.1 TEMPLATES AND GENERIC PROGRAMMING
▪ Templates are powerful features of C++, which allows a programmer to write
generic programs.
▪ Templates are the foundation of generic programming. So it involves writing code in
a way that is independent of any particular type.
▪ A template is a blueprint or method for creating a generic class or a generic
function. It means we can create a single function or a class to work with different
data types using templates.
▪ It uses template concept.
▪ As a feature of C++, it allows functions and classes to operate with generic types.
▪ This allows a function or class to work on many different data types without being
rewritten for each one.
▪ We can use templates to define functions as well as classes. Therefore, it comes in
two forms.
o Function Template.
o Class Template.
template<class T>
T someFunction( T arguments )
{
... .. ...
}
A function template starts with the keyword “template” followed by template
parameters inside <> and then function declaration.
So, in above syntax:
T is a template argument that accepts different data types (int, float, double),
and class is a keyword. When, an argument of a data type is passed
to someFunction( ), compiler generates a new version of someFunction() for the given
data type.
Example of Function Template:
//Function Template to find the largest number
#include <iostream>
int main()
return 0;
}
Output
10
10 is larger.
12.4
10.2
12.4 is larger.
#include <iostream>
class temp
{ private:
T a, b, c;
public:
void get ()
cin>>a>>b; }
void sum ()
{ c = a+b;
cout<<"\nSUM = "<<c; }
};
int main()
o1.get ();
o1.sum ();
o2.get ();
o2.sum ();
o3.get ();
o3.sum ();
return 0;
}
Output:
Give integer values:
Enter two numbers to find addition 10 20
SUM = 30
Give double values:
Enter two numbers to find addition 200.22 300.33
SUM = 500.55
Give float values:
Enter two numbers to find addition 2.2 3.9
SUM = 6.1
◆◆◆◆◆
Chapter 11
Files
11.1 FILE STREAM
A file stream act as an interface between the program (where programmer writes code)
and the files (permanent storage on disk of computer).
The stream used to read from file is known as input stream. This file stream supplies
data to the program i.e. programmer reads from file.
The stream used to write into file is known as output stream. This file stream receives
data from the program i.e. programmer writes into file.
Figure below represents two types of stream with which either write in file or read from
file operations are performed.
There streams are:
1. Input stream
2. Output stream
Functions dealing with input stream are related with reading or extracting purpose
but functions dealing with output stream are related with writing or inserting purpose.
2. Fail ()
● It returns TRUE value if an operation (input or output) is unsuccessful means fail.
● Otherwise: returns FALSE value.
● It can be carried by reading the bits: ios::failbit,
● ios:: badbit and sometimes ios::hardfail of ios::state is checked.
Use in program:
while (!fin.fail () )
{
//Read until not fail
}
OR
if (fin.fail () )
{
// unable to open file
}
3. Bad ()
● It returns TRUE value if an unrecoverable error occurs or operation going to
perform is not valid.
● So TRUE value indicates bad operation and activation of bad ().
● Otherwise: returns FALSE value.
● Ios::badbit is checked.
Use in program:
if (fin.bad () )
{
// do not perform any operation and must report error
}
4. Good ()
● It returns TRUE value if everything with file is going in good way. So, TRUE value
indicates no error occurred.
● Otherwise: returns FALSE value.
● Overall it can be expressed if good () is active then it means all above functions (fail
(), eof (), bad ()) are false.
● Ios::goodbit is checked.
S
p
ec
ifi
c About it
N
a
m
e
eo
Is 1 when end of file is encountered,
fb
Otherwise it is 0
it
fa Is 1 when a non-fatal I/O error has occurred,
il Otherwise it is 0.
bi (The term non-fatal means not so serious to resolve on the
t support).
b
Is 1 when a fatal I/O error has occurred,
a
Otherwise it is 0.
d
It means something bad has occurred so it becomes active
bi
with value 1.
t
go Is 1 means everything going on is good.
o Otherwise it is 0.
d
bi
t
S
.
Mode About it
N
o
ios::at
2 Opens a file for output and move the read/write
e
control at the end of the file.
3 ios::in Opens a text file for reading.
ios::ou
4 Opens a text file for writing.
t
ios::bi
5 Binary file
nary
Closing a file:
C++ automatically close and release all the allocated memory. But a programmer
should always close all the opened files.
In case, user wants to write in a file and in same program he wants to read whole
contents of this file.
In such case, firstly close the writing operation and then open same file again so that
reading will be performed after completion of writing in it. Same code is written in
above example. Two close functions are used: ofile.close () and ifile.close ();
Following code also tells about the use of close ( ) at the end after performing an
operation in an opened file.
//use of close ( ) function
#include <iostream.h>
#include <fstream.h>
void main()
{
ofstream file;
file.open ("example.txt");
file.close( );
getch();
}
Example illustrates Writing in a File:
#include<iostream.h>
#include<fstream.h>
#include<conio.h>
void main()
{
char c, u;
char fname[10];
clrscr();
ofstream outfile; //outfile will be used for writing in a file
cout<< "Enter File Name:";
cin>>fname;
outfile.open(fname);
outfile<<”Jasrat”;
outfile<<”\n Age ”;
outfile<<”2”;
cout<< "Check file contents written recently ”;
outfile.close();
getch();
}
Output:
Enter File Name: contents.txt
Check files contents written recently
In contents.txt file, following contents will be written.
Jasrat
Age 2
Functions used for Accessing File record randomly (Also called File Pointer and their
Manipulator)
Following is list of functions which can be used for randomly accessing records.
1) Seekg ()
2) Seekp ()
3) Tellg ()
4) Tellp ()
Character ‘g’ will get (read) contents from a random location as per need and
character ‘p’ will put (write) contents at a location as per need which can be accessed
randomly.
1. Seekg()
It moves gets pointer (input pointer) to a specified location.
For example:
infile.seekg (10);
Now after this statement, file pointer will point to 10 th byte from starting point.
Now, input pointer will read contents from 10th byte.
It can be written same as below:
infile.seekg(10L, ios::beg); //get contents from 10th byte.
infile.seekg(0, ios::end); //Go to the end of the file as mode is ios::end
2. Seekp()
It moves the puts pointer (output pointer) to a specified location.
For example:
Infile.seekp (15);
Now after this statement, file pointer will point to 15 th byte from starting point. Now, output
pointer will point to 15th byte for writing further contents.
The contents from 15th byte will be automatically shifted forward.
3. Tellg()
It tells about current position of get pointer.
Double size = infile.tellg ();
// It will tell (get) the file pointer position.
4. Tellp()
It tells about current position of put pointer.
double size = outfile.tellp ();
//It will tell (put) the file pointer position
Note:
Seekg () and tellg () functions combination can be used to determine the actual data
length of a file.
Common about functions seekg () and tellg ():
Both seekg () and tellg () work for ifstream objects because ifstream deals with reading
and get also indicates reading contents. Also both these functions allow user to set
and examine the gets_pointer,
Common about functions seekp() and tellp() :
Both seekp() and tellp() functions work for ofstream objects because ofstream deals
with writing and put also indicates writing contents. Also both thses functions perform
operations on the puts_pointer.
Name of Member Functions of Input Stream:
Input stream member functions are used for disk input. The member functions list is:
1) open () function for input streams
2) get ()
3) getline()
4) read()
5) seekg()
6) tellg()
7) close() function for input streams
Name of Member Functions of Output Stream:
Output stream member functions are used for screening output. The member
functions include:
1) open () function for output Streams
2) put ()
3) putline()
4) write()
5) seekp()
6) tellp()
7) close() function for output Streams.
◆◆◆◆◆