Object Oriented Programming
Object Oriented Programming
private:
datatype member_variables;
datatype member_functions;
public:
datatype member_variables;
datatype member_functions;
};
int main() {
class_name object_name;
}
The code above shows that a class acts like a single unit consisting of
member variables and member functions.
Let's take one example to understand the concept of data encapsulation:
class A{
private:
int var;
public:
void takeInput()
{
cin >> var; In the above example, as we can see
} class A acts like a single unit consisting of
void display()
{
member variables and member functions
cout << var << endl; operating on those member variables. Here,
} the variable “var” is private.
Hence, this variable can be accessed only by
};
the members of the same class and is not
int main(){ accessible anywhere else. Hence the outside
classes will be unable to access this variable
A obj; which will help in achieving data hiding.
obj.takeInput();
obj.display();
}
OUTPUT:
20
20
Real-life example
• Suppose you go to an automatic teller machine(ATM) and
request money. The machine processes your request and
gives you money.
• Here ATM is a class. It takes data from the user(money
amount and PIN) and displays data in the form of icons and
options. It processes the request(functions). So it contains
both data and functions wrapped/integrated under a single
ATM. This is called Encapsulation.
• Suppose you have a profile on some social networking
website, say Facebook. If your profile password is declared
as a public variable, anyone can see your password and log
in to your Facebook account. So, would you like it?
Obviously No.
So, Facebook declares your password as private to make
your account safe so that anyone can not log in to your
account. So the other details of your account or post you
share can be made public or private by you. So you can see
the data hiding concept here.
Advantages/disadvantages of Encapsulation in C++
Advantages
• The main advantage of using Encapsulation is to hide the
data from other methods. By making the data private,
these data are only used within the class, but these data
are not accessible outside the class.
• Protects data from unauthorized users
• This concept is applicable in the marketing and finance
sector, where there is a high demand for security and
restricted data access to various departments.
• Encapsulation helps us in binding the member functions
and data of a class.
• Encapsulation also helps us make code flexible, which is
easy to change and maintain.
Disadvantage
• Private data cannot be accessed outside the class.
How to Use Encapsulation in C++?
• First, make all the data
members private.
• Then getter(gets the value of data
member) and setter (sets the value of
data member)functions should be
performed for each data member.
• In this, we are adding an
employee’s salary (full-time and
overtime). We have a data member
salary declared as private, as you can
see. That means it can be used within
that class only and not even in
the main(). If we want to use this
function in the main function, we
should use the getter and setter
functions. So here we have a getter
function getSalary() and setter
function setsalary().
• Inside main(), we create an object of
the company class. Now we can use
the setSalary() method to set the value
of the full-time and overtime salaries.
Then we call the getSalary() method on
the object to return the value.
ENCAPSULATION
Abstraction:
• Process of picking the essence of an object you really need
• In other words, pick the properties you need from the object
• Example:
a. TV - Sound, Visuals, Power Input, Channels Input.
b. Mobile - Button/Touch screen, power button, volume button, sim port.
c. Car - Steering, Break, Clutch, Accelerator, Key Hole.
d. Human - Voice, Body, Eye Sight, Hearing, Emotions.
Encapsulation:
• Process of hiding the details of an object you don't need
• In other words, hide the properties and operations you don't need from the object but are
required for the object to work properly. Example:
a. TV - Internal and connections of Speaker, Display, Power distribution b/w components,
Channel mechanism.
b. Mobile - How the input is parsed and processed, How pressing a button on/off or changes
volumes, how sim will connect to service providers.
c. Car - How turning steering turns the car, How break slow or stops the car, How clutch
works, How accelerator increases speed, How key hole switch on/of the car.
d. Human - How voice is produced, What's inside the body, How eye sight works, How
hearing works, How emotions generate and effect us.
ABSTRACTION
1. What is Abstraction?
• Abstraction is the process of hiding the internal details of an
application from the outer world. Abstraction is used to describe
things in simple terms. It’s used to create a boundary between the
application and the client programs.
2. Abstraction in Real Life
• Abstraction is present in almost all the real life machines.
• Your car is a great example of abstraction. You can start a car by
turning the key or pressing the start button. You don’t need to
know how the engine is getting started, what all components your
car has. The car internal implementation and complex logic is
completely hidden from the user.
• We can heat our food in Microwave. We press some buttons to set
the timer and type of food. Finally, we get a hot and delicious meal.
The microwave internal details are hidden from us. We have been
given access to the functionality in a very simple manner.
• Objects are the building blocks of Object-
Oriented Programming.
• An object contains some properties and
methods. We can hide them from the outer
world through access modifiers.
• We can provide access only for required
functions and properties to the other
programs.
• This is the general procedure to implement
abstraction in OOPS.
Data Abstraction
• Data Abstraction is a mechanism or technique of showing the users only
the necessary interface details and hiding the complex and complicated
implementation details from the user. It's the process of providing only the
essential details to the outside world and hiding the internal complex
details.
• We can understand the concept of data abstraction with the help of an
example: let's suppose you want to sort a list of numbers in your C++
program, so for that, you can make a call to the sort() function without
knowing what algorithm the function actually uses to sort the given
values. Similarly, we use the pow() function to calculate the power of a
number without knowing the algorithm the function follows.
• This is done to hide the internal unnecessary details from the end-
users and to make their task easier.
Data abstraction can be achieved by two types:
Using classes.
Using header files.
Abstraction Using Classes: An abstraction can be achieved
with the help of classes. As we know that a class is a
group of all the data members and member functions
and it binds them all into a single unit.
A class has the responsibility to determine which data
member is to be visible and accessible outside the class
and which is not with the help of the access specifiers.
Let's see a simple example to understand abstraction using
classes:
class Base
{
private: In this example, abstraction is achieved using
int num1, num2, subtract; // private variables classes. Class Base contains the private
members num1, num2, and subtract, and are
public: only accessible by the member functions of
void fun()
the class.
{
cout << "Enter two numbers:" << endl;
cout << "The difference between the two numbers is:" << endl;
if(num1 > num2)
{
subtract = (num1 - num2);
}
else
{
subtract = (num2 - num1);
}
cout << subtract << endl; OUTPUT:
} Enter two numbers:
};
int main() 10
{ 60
Base obj; The difference between the two numbers is:
obj.fun();
}
50
• Abstraction in Header Files: Abstraction can also be achieved using
header files. As we have seen above, the pow() function is used
to calculate the power of a number without actually knowing which
algorithm function uses to calculate the power. We can simply use the
pow() function in our code after importing the necessary header files.
Thus, we can say that header files hides all the implementation details
from the user.
• Let's take one simple example to understand abstraction in header files:
#include<math.h>
int main()
{
cout << pow(4, 3) << endl;
}
OUTPUT
64
• As we can see from the above code, we can simply use the pow() function
in our code after importing the necessary header file i.e math.h, even
without knowing which algorithm the pow() function uses to calculate the
power.
• Consider a real-life example of a man driving a car.
The man only knows that pressing the accelerator will
increase the speed of the car or applying brakes will
stop the car but he does not know how on pressing the
accelerator the speed is actually increasing, he does not
know about the inner mechanism of the car or the
implementation of the accelerator, brakes, etc in the
car. This is what abstraction is.
• Types of Abstraction:
• Data abstraction – This type only shows the required
information about the data and hides the unnecessary
data.
• Control Abstraction – This type only shows the
required information about the implementation and
hides unnecessary information.
Abstraction using Classes
• We can implement Abstraction in C++ using classes. The class helps us to group
data members and member functions using available access specifiers. A Class can
decide which data member will be visible to the outside world and which is not.
Syntax:
class subclass_name : access_mode base_class { // body of
subclass }; OR class A { ... .. ... }; class B: public A { ... .. ... };
• 2. Multiple Inheritance: Multiple Inheritance
is a feature of C++ where a class can inherit
from more than one class. i.e one subclass is
inherited from more than one base class.
• 3. Multilevel Inheritance: In this type of inheritance, a
derived class is created from another derived class.
• class C { ... .. ... }; class B:public C { ... .. ... }; class A:
public B { ... ... ... };
• 4. Hierarchical Inheritance: In this type of inheritance,
more than one subclass is inherited from a single base
class. i.e. more than one derived class is created from a
single base class.
•
Syntax:-
• class A { // body of the class A. }
• class B : public A { // body of class B. }
• class C : public A { // body of class C. }
• class D : public A { // body of class D. }
• 5. Hybrid (Virtual) Inheritance: Hybrid Inheritance
is implemented by combining more than one type
of inheritance.
• For example: Combining Hierarchical inheritance
and Multiple Inheritance.
Below image shows the combination of hierarchical
and multiple inheritances:
• 6. A special case of hybrid inheritance:
Multipath inheritance:
A derived class with two base classes and these
two base classes have one common base class is
called multipath inheritance. Ambiguity can arise
in this type of inheritance. There are 2 Ways to
Avoid this Ambiguity:
• 1) Avoiding ambiguity using the scope resolution
operator: Using the scope resolution operator we
can manually specify the path from which data
member a will be accessed
• 2) Avoiding ambiguity using the virtual base
class
DATA HIDING
• Data is the most confidential and sensitive information
that must be kept safe and protected against unwarranted
disclosure from all outsiders unless they have permission to
access it.
• Data hiding is an object-oriented programming technique
for protecting the data within a class from unwanted
access and preventing unneeded intrusion from outside the
class. It helps in hiding internal object details, i.e., data
members within the class to prevent its direct access from
outside the class. Data hiding is also known as Information
hiding
• Data hiding guarantees the restricted access of data from
unwanted sources and maintains data integrity by
preventing unintended or intended changes.
• The term "data hiding" refers to the process
of concealing or hiding the data from program
components that don't need to be retrieved. Data
hiding helps in the protection of a class's members.
• The data members and the member functions in a
class are made private using data hiding so that they
cannot be accessed falsely by functions outside the
class and are protected from accidental modifications
and changes. This helps in providing object integrity
and in preventing unintended or intended changes.
• Let's take one example to
understand the concept of
data hiding:
• Suppose, there is a
class A having a
variable var and two
functions, one to input the
number from the user and
the other to display the
variable entered by the user
on the screen. Here, we will
declare the variable "var" as
private so, that it can be
accessed only by the
members of the same class,
and it can't be accessed
anywhere else. Hence, we
will be unable to access this
variable outside the class,
which is called data hiding.
• Applications of Data Hiding
• It helps in protecting sensitive information against
unwarranted disclosure from all outsiders unless they have
permission to access it.
• It helps in isolating the objects as the basic concept of
object-oriented programming, which means that objects
within the class are disconnected from irrelevant data.
• It helps in increasing the data security against hackers
which helps in ensuring that they are unable to access
confidential data.
• It helps to prevent damage to volatile and sensitive data by
hiding it from the public.
Benefits of Data Hiding
• Benefits of data hiding includes:
• Increased data protection and security against hackers.
• It ensures data assurance from corruption and unwarranted access.
• It is used to minimize data complexity.
• It increases the program’s reusability.
• It helps in defining the interface clearly and improves readability
and comprehensibility.
• It reduces system complexity and increases robustness by limiting
interdependencies between software components.
Disadvantages of Data Hiding
• The disadvantage of data hiding in c++ is that it requires additional
coding in order to achieve the desired effect in hidden data. This
makes the code lengthier. So, data hiding can be a harder process
for a programmer, and he may need to write lengthy codes to
create effects in the hidden data.
• The link between the visible and invisible data makes the objects
work faster, but data hiding prevents this linkage, and so the
process becomes slow.
Access Specifiers
• To support the features of data hiding in
c++, abstraction, and encapsulation in object-oriented
programming, we have the concept of access
specifiers.
• The access restriction to the class member functions is
specified by access modifiers.
• Access modifiers are also known as visibility modes in
C++, and there are three types of visibility modes:
public, private, and protected.
• Access specifiers are mainly used for data hiding in c++
and encapsulation as they can help us to control what
part of a program can access the members of a class.
So that misuse of data can be prevented.
• Public Visibility Mode:
• In public visibility mode, when we inherit a child
class from the parent class, then the public,
private, and protected members of the base class
remain public, private, and protected members
respectively in the derived class as well.
• The public visibility mode retains the accessibility
of all the members of the parent class.
• The public members of the parent class are
accessible by the child's class and all other
classes.
• The protected members of the base class are
accessible only inside the derived class and
its inherited classes.
• However, the private members are not accessible
to the child class.
• The syntax of using Visibility Modes is:
class child_class_name :: visibility_mode parent_class_name
{
}
The visibility_mode can be public, private or protected.
• Let's see an example to understand the concept of public visibility
mode:
class Parent
{ The protected variable x2 will be inherited
private: from the Parent class and will be accessible in
int x1; the Child class, similarly, the public
variable x3 will be inherited from the Parent
protected: class and will be accessible in the Child class,
but the private variable x1 will not be
int x2; accessible in the Child class.
public:
int x3;
};
class Child: public Parent
{
};
• Private Visibility Mode:
• In the private visibility mode, when we inherit a
child class from the parent class, then all the
members (public, private and protected
members) of the base class will
become private in the derived class.
• The access of these members outside the derived
class is restricted and they can only be accessed
by the member functions of the derived class.
Let's see an example to understand the concept of private visibility mode:
class Parent
{
private:
int x1; As the visibility mode is private, so, all the
members of the base class have become
protected: private in the derived class. The error is thrown
int x2; when the object of the derived class tries to
access these members outside the derived
public: class.
int x3;
};
class Child: private Parent
{
};
• Protected Visibility Mode:
• In the protected visibility mode, when we inherit
a child class from the parent class, then all the
members of the base class will become
the protected members of the derived class.
• Because of this, these members are now only
accessible by the derived class and its member
functions. These members can also be inherited
and will be accessible to the inherited subclasses
of this derived class.
Let's see an example to understand the concept of protected visibility mode:
class Parent
{
private:
int x1;
As the visibility mode is protected, the
protected: protected and the public members of the
int x2; Parent class become the protected members
of the Child class.
public: The protected variable x2 will be inherited
int x3; from the Parent class and will be accessible in
}; the Child class, similarly, the public
class Child: protected Parent variable x3 will be inherited from the parent
{ class as the protected member and will be
accessible in the Child class, but the private
}; variable x1 will not be accessible in the Child
class.
SUMMARY
Data hiding is an object-oriented programming technique for protecting the
data within a class from unwanted access and preventing unneeded intrusion from
outside the class.
Data abstraction is the process of providing only the essential details to the
outside world and hiding the internal complex details.
Data encapsulation is the process of wrapping or bundling the data members and
member functions into a single unit as a capsule known as a class.
Access specifiers are used to provide access restrictions to the class member
functions. There are three access specifiers: public, private, and protected.
When the members in the class are declared as public, then they are accessible
from anywhere.
When the members in the class are declared private, then, they are only accessible
by the members of the base class.
When the members in the class are declared as protected, then, they are
accessible in the base class and the derived classes.
Private access specifier provides more security to its data members as compared
to the public and protected access specifier.
Access modifiers are mainly used for data hiding in c++ and encapsulation as they
can help us to control what part of a program can access the members of a class.
So that misuse of data can be prevented.
POLYMORPHISM
• Polymorphism means one thing has different forms.
Polymorphism allows a member function of a class to
behave differently based on the object that will call it.
Polymorphism occurs when classes are related through
inheritance.
• You can take an example:
• Suppose there is a function playInstrument() in parent class
“Instrument” and Instrument class have two child classes or
sub-classes: “Guitar“ and “Trumpet” and playInstrument
will return the sound produced by the instrument which
will call that function. So if the Guitar class object will call
playInstrument then Guitar sound will be the output and if
the Trumpet class object will call playInstrument then
Trumpet sound will be the output.
• Polymorphism can be achieved through function overloading and
function overriding.
Function overriding: In function overriding child class can exhibit
different implementation of the same function which has been
defined in parent class also, according to its usages.
• The above example of “Instrument” class is an example of Function
overriding.
Function overloading: Polymorphism is also achieved through function
overloading. In function overloading, methods can have the same
name but the number of arguments is different in function calls.
Results will be different according to the number of arguments with
which the function is called.
• You can take a real-life example. Suppose you created a function to
calculate areas of a figure to calculate the area of rectangle and
square. As you know rectangle area is lengthbreadth and square’s
area is sideside so rectangle area function should take 2 arguments
length and breadth whereas square area will take one argument
that is side.
• So instead of creating functions with separate names, you can
create two functions with the same name but the number of
arguments is different for both functions.
//1- for square
int Findarea(int side) findArea(3) call will go to 1 function as the
number of arguments in function is one and
{ findArea(2,5) call will go to 2 function as the
number of arguments in the function call is
return side * side; two. This is the concept of function
overloading.
}
//for rectangle
int Findarea(int length, int breadth) {
return length * breadth;
}
FUNDAMENTAL DATA TYPES
• In C++, every variable use data types to define the type of
data it can store.
• As, we already know variables are something which stores
data. So, data types are used to specify before the
compilation that what type of data the variable is going to
store.
• C++ is said to be stongly typed language which actually
means we have to define the data type of the variable
before using it.Each data type has its own size in memory.
• There are mainly two types of data types in C++:-
Fundamental data types
User defined data types
Fundamental Data types
• Fundamental data types are the data types which
are predefined in the language and can be
directly used to declare a variable in C++.
• The various fundamental data types are:
char (Character)
int (Integer)
float (Floating point)
bool (Boolean)
double (Double floating point)
void (valueless)
1. Character
• It is the datatype that is used to store
characters like a,b,c etc.
• To define Character in C++ we
use char keyword.
• Size of char datatype is 1 byte i.e 8 bits.
• It's range is from -128 to 127 or it can be 0-
255.
Syntax:-
• char a;
• where 'a' is variable.
2. Integer
• It is the datatype that is used to store integer values like 1,2,-1 etc.
• To define Integer in C++ we use int keyword.
• Size of int datatype is 4 byte i.e 32 bits.
• It's range is from -2147483648 to 2147483647.
• Syntax:-
• int a;
3. Floating point
• It is the datatype that is used to store floating values or decimal
values like 1.1,2.1 etc.
• To define Floating point in C++ we use float keyword.
• Size of float datatype is 4 byte i.e 32 bits.
• It's range is from +/- 3.4e +/- 38 (~7 digits).
• Syntax:-
• float a;
4. Boolean
• It is the datatype that is used to store two values only i.e true or
false.
• To define Boolean in C++ we use bool keyword.
• Size of bool datatype is 1 byte i.e 8 bits.
• Syntax:-
• bool a;
Output
a + b = 9 a - b = 5 a * b = 14 a / b = 3 a % b = 1
2. C++ Assignment Operators
• In C++, assignment operators are used to assign values to
variables. For example,
• // assign 5 to a a = 5;Here, we have assigned a value of 5 to
the variable a.
#include <iostream>
using namespace std;
int main() {
int a, b;
// 2 is assigned to a
a = 2;
// 7 is assigned to b
b = 7;
return 0;
}
• 3. C++ Relational Operators
• A relational operator is used to check the relationship between two operands. For
example,
// checks if a is greater than b
a > b;
• Here, > is a relational operator. It checks if a is greater than b or not.
• If the relation is true, it returns 1 whereas if the relation is false, it returns 0.
#include <iostream>
using namespace std;
int main() {
int a, b;
a = 3;
b = 5;
bool result;
return 0;
}
4. C++ Logical Operators
• Logical operators are used to check whether an expression
is true or false. If the expression is true, it returns 1 whereas if
the expression is false, it returns 0.
Suppose,
a = 5 b = 8
• Disadvantages:-
• Size Limit: We can store only the fixed size of elements in the array. It doesn’t grow
its size at runtime.
CONTROL FLOW IN OOPS
• 1. Branching or Conditional Structure –
• In the normal state, execution of the program is
gradual execution. When the Sequential
Execution of the program is blocked by the
selected Statements, it is called Branches
Execution.
• Control of the program requires a condition to
block selected statements. That is, the control of
the program is done by blocking the selected
statements based on a condition, then the
statement used in it is called Conditional
Statement.
• C ++ consists of three Conditional Statements –
• 2. Iterative or looping Structure –
• Looping or Reversible Statement Program sometimes requires the
same statement to be used repeatedly, for this C ++ has three
methods.
• Using which we can execute statements repeatedly which are the
following are also called Looping Statements.
• Through loops, we can execute anyone’s statement or many
abstract statements more than once until the condition is achieved.
• 1. While loop –
• while loop is an entry-controlled loop. In this, the
statement keeps executing continuously until a
condition is true. It first checks the condition and later
executes the statement.
• It is necessary to initialize the variable in While Loop.
• If while Loop is to be repeated, the
increment/decrement operator is used.
• Repeats until the condition in While Loop is true.
• syntax:-
while(condition)
{
statement1;
statement2;
————-
}
2. Do while loop –
• This loop is exit-controlled. This loop is also like a while
loop but it executes the first statement and checks the
condition later.
• Repeats until the condition in Do-While Loop is true.
• The specialty of Do-While is that, even if the condition is
false, it prints a statement in the output.
• This loop ensures that the program is executed at least
once.
• syntax:-
do
{
Statement1;
Statement2;
————–
}
While (condition);
• 3. For loop –
• For Loop only needs a Variable Declaration. Except for this
statement, he does all the work inside himself.
• Repeats until the condition in While Loop is true.
• This is an entry controlled loop. In this, the statement is
executed until the condition becomes true. This loop
consists of three components initialization statement,
Boolean statement, and increment/decrement statement.
• syntax:-
for(initial condition, test condition; incrementor or
decrement)
{
statement1;
statement2;
}
• 4. Nested loop –
• Nested loop in C ++ Programming is not a type of
loop. Here, in a program, you use the same loop
two or more times, it is called a nested loop.
• For loop is used in this program. If you want, you
can also use the if, while, switch case. It has no
syntax, it depends on writing your program.
• while loops are executed only. As the name
suggests, another loop can be executed inside a
loop.
• 3. Sequential Control Flow Structure –
• The statements written in the program are
implemented one after the other.
• The statements are executed in the order in which the
compiler is received.
• This execution of the program is called serial execution.
• Jump statements –
• Jump statements are used to interrupt the normal
flow of program.
• 1. Break statement –
• This statement is used to end a sequence of statements in a switch
statement and to immediately exit a loop.
• The execution of the loops and switch cases of the Break Statement
Program stops at any condition.
• syntax:- break;
• #include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 10; i++)
{
if (i == 5)
{
break;
}
cout<<i<<“\n”;
}
}
• 2. Continue statement –
• The continue statement is used when we want to run the loop
continues with the next iteration and skip other statements in the
loop for the current iteration.
• Depending on the condition of the loops of the Continue Statement
program, skip the middle statements, and execute the subsequent
statements.
• syntax:- continue;
• #include <iostream>
using namespace std;
int main()
{
for(int i=1;i<=10;i++){
if(i==5){
continue;
}
cout<<i<<“\n”;
}
}
3. Go to statement –
• Go to is the statement of C ++ Programming. Labels are used in this.
• There are two types of Go to Statements.
• Forward
• Backward
• When a goto statement executes its next statement except for some statement, it
is called Forward goto statement and goes to its previous label to execute any
previous or executed statement again, it is called Backward goto statement.
Output: 5
The new operator is used to dynamically allocate memory for the
variable on the heap, which is a region of memory that remains
allocated until explicitly deallocated using the delete operator. The
pointer pnt is used to access the memory location where the int is
stored.
• What is a delete operator?
• The delete operator is used to deallocate memory that was
previously allocated on the heap using new. It takes a pointer to the
memory to be deallocated as an argument. For example:
• delete p; // Deallocates the memory pointed to by p
• The “delete” operator is used to deallocate memory that the “new”
operator previously allocated. Once a block of memory has been
allocated by “new,” it is important to deallocate it when it is no
longer needed so that other parts of the program can reuse the
memory. The “delete” operator releases the memory back to the
system, and other parts of the program can use it.
• Note: Use delete to deallocate memory allocated with new to avoid
memory leaks.
• Memory leaks occur when the program allocates memory
dynamically but does not deallocate it properly. This causes the
program to consume more memory gradually, eventually leading to
poor performance or even crashing the program.
New and delete operators example
#include <iostream>
int main()
{
int* ptr1 = new int; // dynamically allocate memory for an int
*ptr1 = 5; // store the value 5 in the allocated memory
float *ptr2 = new float(20.324);
int *ptr3 = new int[28];
Output
std::cout << "Value of pointer variable 1 : " << *ptr1<<std::endl;
std::cout << "Value of pointer variable 2 : " << *ptr2<<std::endl;
Value of pointer variable 1 :
if (!ptr3) 5
std::cout << "Allocation of memory failed\n"; Value of pointer variable 2 :
else { 20.324
for (int i = 1; i < 15; i++) Value of store in block of memory:
ptr3[i] = i+1; 2 3 4 5 6 7 8 9 10 11 12 13 14 15 5
std::cout << "Value of store in block of memory: ";
for (int i = 1; i < 15; i++)
std::cout << ptr3[i] << " ";
}
std::cout << *ptr1; // output the value stored in the allocated memory
delete ptr1;// deallocate the memory to prevent memory leak
delete ptr2;
delete ptr3;
return 0;
}
• The first line uses the “new” operator to allocate memory
dynamically for an integer variable and assigns the allocated
memory address to the pointer variable ptr1. The value 5 is stored
in the allocated memory using the pointer variable ptr1.
• The second line uses the new operator to allocate memory for a
float variable dynamically, and assigns the allocated memory
address to the pointer variable ptr2. The value 20.324 is also
assigned to this pointer.
• The third line uses the new operator to dynamically allocate
memory for an array of 28 integers and assigns the allocated
memory address to the pointer variable ptr3.Then the code uses
std::cout to output the values stored in the allocated memory for
the pointer variables ptr1, ptr2, and ptr3.
• In the final lines of the code, the delete operator is used to
deallocate the memory allocated for the pointer variables ptr1,
ptr2, and ptr3 to prevent memory leaks.
• It’s worth noting that in the case of the array (ptr3), the code uses
the if (!ptr3) statement to check if the memory allocation was
successful or not, otherwise it will store values in the array and
output the values stored in the array using a for a loop.
When to do dynamic memory allocation?
• When the size of the data structure needs to change at runtime: For
example, if a program needs to store a large number of items in an
array, and the number of items is not known at compile time,
dynamic memory allocation can be used to create an array of the
appropriate size.
• When working with complex data structures: Dynamic memory
allocation can be used to create linked lists, trees, and other
complex data structures that require a flexible amount of memory.
• When working with polymorphic objects: Dynamic memory
allocation is often used to create objects of different types at
runtime. For example, a program might use dynamic memory
allocation to create objects of different classes inherited from a
common base class.
• When working with large data sets: Dynamic memory allocation can
handle large data sets that cannot fit in the stack memory.
• When memory is being used very efficiently: Dynamic memory
allocation can ensure that the program uses only as much memory
as it needs, rather than allocating a fixed amount of memory at
compile time.
Inline Function
• Inline function in C++ is an enhancement feature that improves the
execution time and speed of the program.
• When an instruction of a function call is encountered during the
compilation of a program, its memory address is stored by the
compiler.
• The function arguments are copied on the stack and after the
execution of the code, the control is transferred to the calling
instruction.
• This process can sometimes cause overhead in function calls,
especially if the function is small and its execution time is less than
the switching time.
• This issue is resolved by using the inline functions.
• These functions overcome the overhead and also make the
program faster by reducing the execution time of the program.
• Following are some key points that you need
to keep in mind while dealing with inline
functions:
• Inline functions that are small have higher
efficiency and better results than the lengthier
inline functions. So, try to keep your inline
functions small in length.
• Although these functions increase the
efficiency of the program and improve its
execution, you should not convert all the
functions into inline functions. If you convert
larger functions to inline, it may lead to code
bloat and reduce the functioning quality of
the program.
• Always try to define large functions outside
the class, since functions defined inside a class
are automatically defined as inline and this
will affect the program negatively. You can use
scope resolution (::) for this purpose.
Syntax of Inline Function in C++
• The syntax for defining the function inline is:
inline return_type function_name(data_type arg1 , data_type
arg2 )
{
// definition of the function
}
Syntax explanation:
• Keyword “inline”: The keyword inline is specified at the
beginning to tell the compiler that the function is an inline
function. However, it’s up to the compiler to decide
whether to inline a function or not.
• Defining the function: An inline function needs to be
defined when it is declared. Whenever there is a call to the
function in the program, the compiler will simply replace it
with the function’s definition.
• When to Use the Inline Function?
• Inline functions are very efficient and can be used in
various areas of a program. But there are some cases
where you can utilize the maximum features of these
functions and extract the maximum output from them.
Some of these cases are:
• Inline functions prove to be the best when it comes to
performance. If you need the performance in your
program, you must go with inline functions as they
enhance the execution time and speed of your
program.
• If you want to hide the implementation details of your
functions, you can define the inline functions outside
the class by using the inline keyword.
• Advantages of Inline Function in C++
• The compilation speed of the program gets increased
since the inline functions prevent function call
overhead.
• Inline functions that are small in length can be used in
embedded systems as well since these functions yield
lesser code than the function call and return.
• These functions also prevent the overhead of function
return calls.
• They allow the compiler to perform some
optimizations on the body of the function that is
content-specific in nature. Such optimizations cannot
take place for other function calls.
• During the invoking or calling of the function, these
functions prevent the overhead of push and pop stack
variables.
• Disadvantages of Inline Function in C++
• Inline functions must be short in length as lengthier inline functions
can cause a reduction of the cache hit rate of the instructions. This
can have adverse effects on the efficiency of the program.
• Excess use of inline functions in the code may lead to the
enlargement of the size of the binary executable code.
• In the case of large functions, compilation overhead can take place
and reduce the efficiency of the code.
• Implementation of these functions in the header files can make
them heavy.
• Since storage is not allocated to such functions and they are stored
in a symbol table, the compiler cannot perform the inlining of these
functions, and hence you can not get the address of these
functions.
• Large inline functions are useless for embedded systems since these
systems give preference to the size of the function over speed.
When the above code is compiled and executed, it produces the following result −
Max (20,10): 20
Max (0,200): 200
Max (100,1010): 1010
Friend function
• A friend function in C++ is defined as a function that can
access private, protected and public members of a class.
• The friend function is declared using the friend keyword
inside the body of the class.
• friend class class_name; // declared in the base class
• Data hiding is a fundamental concept of object-oriented
programming. It restricts the access of private members from
outside of the class.
• Similarly, protected members can only be accessed by derived
classes and are inaccessible from outside. For example,
class MyClass
{ private: int member1;
}
int main()
{
MyClass obj;
// Error! Cannot access private members from here.
obj.member1 = 5; }
However, there is a feature in C++ called friend functions that break this rule and allow us to
access member functions from outside the class.
#include <iostream>
using namespace std;
// friend function
friend int addFive(Distance);
Here, addFive() is a friend function that can
public:
access both private and public data members.
Distance() : meter(0) {}
Though this example gives us an idea about the
}; concept of a friend function, it doesn't show
any meaningful use.
// friend function definition
int addFive(Distance d) { A more meaningful use would be operating on
objects of two different classes. That's when
//accessing private members from the friend function the friend function can be very helpful.
d.meter += 5;
return d.meter;
}
int main() {
Distance D;
cout << "Distance: " << addFive(D);
return 0;
}
Example 2: Add Members of Two Different Classes
// Add members of two different classes using friend functions
#include <iostream>
using namespace std;
// forward declaration
class ClassB; OUTPUT:
class ClassA {
Sum: 13
public:
// constructor to initialize numA to 12
ClassA() : numA(12) {}
private:
int numA; In this program, ClassA and ClassB have
// friend function declaration declared add() as a friend function. Thus, this
friend int add(ClassA, ClassB); function can access private data of both classes.
}; One thing to notice here is the friend function
class ClassB { inside ClassA is using the ClassB. However, we
public:
haven't defined ClassB at this point.
// constructor to initialize numB to 1
ClassB() : numB(1) {} // inside classA
private: friend int add(ClassA, ClassB);
int numB;
// friend function declaration For this to work, we need a forward declaration
friend int add(ClassA, ClassB); of ClassB in our program.
};
// forward declaration
// access members of both classes class ClassB;
int add(ClassA objectA, ClassB objectB) {
return (objectA.numA + objectB.numB);
}
int main() {
ClassA objectA;
ClassB objectB;
cout << "Sum: " << add(objectA, objectB);
return 0;
}
friend Class in C++
We can also use a friend Class in C++ using the friend keyword. For
example,
class ClassB;
class ClassA
{
// ClassB is a friend class of ClassA friend class ClassB; ... .. ...
}
class ClassB { ... .. ... }
So, we have created two objects for the Test class. Then
every object will have it’s own a and b data members.
Now let us understand static data members. We are
defining a static variable in the above class as follows:
• So here inside the Test class, we have declared a static integer type
variable that is count. And also, we are incrementing its value by 1
in the constructor of the class Test. Here, the count is a static
variable. Then how does it works? When we are creating an object
t1 then how many members are there and for which memory will
be allocated? a, b and count. And when we are creating an object
t2, again a, b, and the count will be there. For a better
understanding, please have a look at the below image.
• As you can see in the above diagram, both t1 and t2 have separate
memory allocations for their a and b data members but the same
memory is shared for the count variable.
• So how many times this count variable is allocated? Only one time
the memory is allocated. And that memory is shared by both the
objects t1 and t2. Both of them will use the same count. So, it
means when we make a variable as static, that variable will occupy
memory only once. So static variables or static data members of a
class belong to a class. That doesn’t belong to an object. And all the
objects can share it. So, there will be only one copy and every
object will share that copy.
• Now let us see what happens. At the time of creating t1, the
constructor will assign a and b variables to 10 and 20 and
increment the count variable by 1. Assume the initial value of the
count is 0. So, after creating the object t1, the count will become 1
as shown in the below image.
• Then when we were creating t2,
the constructor was called that
assign t2’s a and b to 10 and 20
and increments the count. So,
previous the count value was 1,
then after incrementing, it will
become 2 as shown in the
below image.
So, both t1 and t2 have to access the same count variable. Such data members
are static data members of a class. Static members are belonging to a class and
they are common to all the objects. So static members are shareable members of
a class.
• When you have a static variable inside the class, you must have
declared it outside again. So, when we declare the class variable
outside the class, then it will become a global variable but we want
it to be accessible only inside the Test class. So, we can use the
scope resolution operator to make it accessible only inside the Test
class. The statement is,
• int Test::count = 0;
• This is an important statement. When you declared a static member
inside a class then that data member must be declared outside the
class again using the scope resolution operator.
• Now count is a global variable. A global variable is common for the
whole program. There is only one variable created for the entire
program. But we want the count variable to be used only within the
Test class. So, for this, we have given scope resolution to count. So,
two times we need the declaration of the count variable. It is just
like a global variable and you are making it accessible only to the
objects of the Test class. So that is the static variable. Only one-time
memory is allocated and all objects can access it. That’s all about
static data members.
• How to access Static Data Members in C++?
• Now let us see how to access that static variable.
cout << t1.count << endl;
• Can we access it like this? Yes, we can access it because it is
public inside the class. So, what will be displayed here? It
will display 2.
cout << t2.count << endl;
• Can we say this? Yes. So, what will be displayed here? Again
2 will be displayed. As count is public, so we can also write,
cout << Test::count << endl;
• Again 2 will be displayed. So here we have learned a new
thing. Static data members can be accessed using objects
or they can also be accessed using the class name if they
are public. You can directly access them using the class
name. So static member actually belongs to a class and
hence we can access them using the class name.
Output:
{
class A
// object initialization { public:
int i;
} }; A(); // constructor declared
};
// constructor definition
A::A()
{ i = 1;
}
Types of Constructors in C++
Constructors are of three types:
1. Default Constructor
2. Parametrized Constructor
3. Copy COnstructor
Default Constructors
• Default constructor is the constructor which doesn't take any argument. It has no parameter.
Syntax:
class_name(parameter1, parameter2, ...)
{ // constructor Definition }
For example: In this case, as soon as the object is created
class Cube
{ public:
the constructor is called which initializes
int side; its data members.
Cube() A default constructor is so important for
{ side = 10; initialization of object members, that even if
} we do not define a constructor explicitly, the
};
int main()
compiler will provide a default constructor
{ Cube c; implicitly.
cout << c.side;
}
OUTPUT:
10
class Cube OUTPUT:
{ 0 or any random value
public:
int side; In this case, default constructor provided by
}; the compiler will be called which will initialize
the object data members to default value, that
int main() will be 0 or any random integer value in this
{ Cube c; case.
class Employee {
private:
// Data members Employee1 using the parameterized constructor :
int salary, experience;
Salary: 34000
public:
// Parameterized constructor
Years of experience: 2
Employee(int x1, int y1) { Employee2 using copy constructor :
salary = x1;
experience = y1; Salary: 34000
}
Years of experience: 2
// Copy constructor
Employee(const Employee &new_employee) {
salary = new_employee.salary; Explanation:
experience = new_employee.experience; In this example, object employee1 of class Employee is declared in the
} first line of the main() function. The data
members salary and experience for object employee1 are assigned
void display() {
cout << "Salary: " << salary << endl; 34000 and 2, respectively, with the help of a parameterized
cout << "Years of experience: " << experience << endl; constructor, which is invoked automatically. When object employee2 is
} declared in the second line of the main() function, object employee1 is
}; assigned to employee2, which invokes the copy constructor as the
argument here is an object itself. As a result, the data member's salary
// main function
int main() { and experience of object employee2 are assigned to values possessed
// Parameterized constructor by the salary, and experience data members of object employee1 (i.e.,
Employee employee1(34000, 2); 34000, 2), respectively.
// Copy constructor
Employee employee2 = employee1;
cout << "Employee1 using parameterized constructor : \n";
employee1.display();
cout << "Employee2 using copy constructor : \n";
employee2.display();
return 0;
}
• What is a Destructor in C++?
• A Destructor is a member function that is instantaneously called whenever
an object is destroyed. The destructor is called automatically by the
compiler when the object goes out of scope, i.e., when a function ends,
the local objects created within it are also destroyed. The destructor has
the same name as the class name, but the name is preceded by a tilde(~).
A destructor has no return type and receives no parameters.
class scaler
{
public:
//constructor
scaler();
//destructor
~scaler();
};
• Characteristics of a Destructor in C++
• A destructor deallocates memory occupied by the object when it’s
deleted.
• A destructor cannot be overloaded. In function overloading,
functions are declared with the same name in the same scope,
except that each function has a different number of arguments and
different definitions. But in a class, there is always a single
destructor that does not accept any parameters. Hence, a
destructor cannot be overloaded.
• A destructor is always called in the reverse order of the constructor.
In C++, variables and objects are allocated on the Stack. The Stack
follows the LIFO (Last-In-First-Out) pattern. So, the deallocation of
memory and destruction is always carried out in the reverse order
of allocation and construction. This can be seen in the code below.
• A destructor can be written anywhere in the class definition. But to
bring an amount order to the code, a destructor is always defined
at the end of the class definition.
#include <iostream>
using namespace std;
class Department { OUTPUT:
public: Constructor Invoked for Department class
Department() {
// Constructor is defined. Constructor Invoked for Employee class
cout << "Constructor Invoked for Department class" << endl; Destructor Invoked for Employee class
}
Destructor Invoked for Department class
~Department() {
// Destructor is defined.
cout << "Destructor Invoked for Department class" << endl; Explanation:
} When an object named d1 is created in the first line
}; of main(), i.e. (Department d1), its constructor is
class Employee {
automatically invoked during the creation of the
public:
Employee() {
object. As a result, the first line of output,
// Constructor is defined. “Constructor Invoked for Department class,” is
cout << "Constructor Invoked for Employee class" << endl; printed. Similarly, when the e2 object of the
} Employee class is created in the second line
~Employee() {
of main(), i.e. (Employee e2), the constructor
// Destructor is defined.
cout << "Destructor Invoked for Employee class" << endl; corresponding to e2 is invoked automatically by the
} compiler, and “Constructor Invoked for Employee
}; class” is printed.
int main(void) { A destructor is always called in reverse order as that
// Creating an object of Department.
Department d1;
of a constructor. When the scope of the main function
// Creating an object of Employee. ends, the destructor corresponding to object e2 is
Employee e2; invoked first. This leads to printing “Destructor
return 0; Invoked for Employee class”. Lastly, the destructor
}
corresponding to object d1 is called, and “Destructor
Invoked for Department class” is printed.
• Constructors are an essential part of a class definition and
should be designed and built with care as these functions
define how new class objects are to be instantiated. They
allow us to create different instances of our classes.
• A constructor which does not receive any parameters is
called a Default Constructor or a Zero Argument
Constructor.
• A Parameterized Constructor is a constructor that can
accept one or more arguments.
• A Copy constructor is a type of constructor used to create a
copy of an already existing object of a class type.
• When the allocation of memory is done dynamically using a
dynamic memory allocator new in a constructor, it is known
as a Dynamic constructor.
• A Destructor deallocates memory occupied by the object
when it’s deleted.
Object Instantiation
Instantiation in C++
• Used to create an object (class instance) from a class.
•
Syntax
className objectName(parameters);
• Input requirements are taken from the constructor. A class can have multiple constructors with
different numbers of input parameters and types, to create different objects.
• An instance of a class is called an object.
• Example
using namespace std; //class looks like this
class Car
{
public: string make;
Car (string make)
{
this->make = make;
}
};
//instantiation, elsewhere in the program
Car myCar("Honda"); //passing in Honda into the make variable
• The this pointer in C++ points to the object that invokes the
member function. This keyword is only accessible within
the nonstatic member functions of a class/struct/union type.
• Same class variable and parameter names
• When the parameter name is the same as the private variable’s
name, we use the this keyword inside the method to distinguish
between the two when assigning values.
• class ClassName
{
private:
int sameName;
public:
ClassName functionName(int sameName)
{
this->sameName = sameName;
//the variable used with "this", is the class variable
}