0% found this document useful (0 votes)
6 views61 pages

Memory Management in C++: New & Delete Operators

Uploaded by

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

Memory Management in C++: New & Delete Operators

Uploaded by

hmspking372
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

UNIT-V

Memory Management Operators


What is Memory Management?
Memory management is a process of managing computer memory, assigning the memory
space to the programs to improve the overall system performance.

Why is memory management required?

As we know that arrays store the homogeneous data, so most of the time, memory is allocated to
the array at the declaration time. Sometimes the situation arises when the exact memory is not
determined until runtime. To avoid such a situation, we declare an array with a maximum size,
but some memory will be unused. To avoid the wastage of memory, we use the new operator to
allocate the memory dynamically at the run time.

Memory Management Operators

In C language, we use the malloc() or calloc() functions to allocate the memory dynamically at
run time, and free() function is used to deallocate the dynamically allocated memory. C++ also
supports these functions, but C++ also defines unary operators such as new and delete to
perform the same tasks, i.e., allocating and freeing the memory.

New operator

A new operator is used to create the object while a delete operator is used to delete the object.
When the object is created by using the new operator, then the object will exist until we
explicitly use the delete operator to delete the object. Therefore, we can say that the lifetime of
the object is not related to the block structure of the program.

Syntax

pointer_variable = new data-type

The above syntax is used to create the object using the new operator. In the above
syntax, 'pointer_variable' is the name of the pointer variable, 'new' is the operator, and 'data-
type' defines the type of the data.
Example 1:
int *p;
p = new int;
In the above example, 'p' is a pointer of type int.
Example 2:
float *q;
q = new float;
In the above example, 'q' is a pointer of type float.
In the above case, the declaration of pointers and their assignments are done separately. We can
also combine these two statements as follows:
int *p = new int;
float *q = new float;

Assigning a value to the newly created object


Two ways of assigning values to the newly created object:
We can assign the value to the newly created object by simply using the assignment operator. In
the above case, we have created two pointers 'p' and 'q' of type int and float, respectively. Now,
we assign the values as follows:
*p = 45;
*q = 9.8;
We assign 45 to the newly created int object and 9.8 to the newly created float object.
We can also assign the values by using new operator which can be done as follows:
pointer_variable = new data-type(value);
Let's look at some examples.
int *p = new int(45);
float *p = new float(9.8);
How to create a single dimensional array
As we know that new operator is used to create memory space for any data-type or even user-
defined data type such as an array, structures, unions, etc., so the syntax for creating a one-
dimensional array is given below:
pointer-variable = new data-type[size];
Examples:
int *a1 = new int[8];
In the above statement, we have created an array of type int having a size equal to 8 where p[0]
refers first element, p[1] refers the first element, and so on.
Delete operator
When memory is no longer required, then it needs to be deallocated so that the memory can be
used for another purpose. This can be achieved by using the delete operator, as shown below:
delete pointer_variable;
In the above statement, 'delete' is the operator used to delete the existing object,
and 'pointer_variable' is the name of the pointer variable.
In the previous case, we have created two pointers 'p' and 'q' by using the new operator, and can
be deleted by using the following statements:
delete p;
delete q;
The dynamically allocated array can also be removed from the memory space by using the
following syntax:
delete [size] pointer_variable;
In the above statement, we need to specify the size that defines the number of elements that are
required to be freed. The drawback of this syntax is that we need to remember the size of the
array. But, in recent versions of C++, we do not need to mention the size as follows:
delete [ ] pointer_variable;
Let's understand through a simple example:
#include <iostream>
using namespace std
int main()
{
int size; // variable declaration
int *arr = new int[size]; // creating an array
cout<<"Enter the size of the array : ";
std::cin >> size; //
cout<<"\nEnter the element : ";
for(int i=0;i<size;i++) // for loop
{
cin>>arr[i];
}
cout<<"\nThe elements that you have entered are :";
for(int i=0;i<size;i++) // for loop
{
cout<<arr[i]<<",";
}
delete arr; // deleting an existing array.
return 0;
}
In the above code, we have created an array using the new operator. The above program will take
the user input for the size of an array at the run time. When the program completes all the
operations, then it deletes the object by using the statement delete arr.
Output

Advantages of the new operator


The following are the advantages of the new operator over malloc() function:
It does not use the sizeof() operator as it automatically computes the size of the data object.
It automatically returns the correct data type pointer, so it does not need to use the typecasting.
Like other operators, the new and delete operator can also be overloaded.
It also allows you to initialize the data object while creating the memory space for the object.
malloc() vs new in C++
Both the malloc() and new in C++ are used for the same purpose. They are used for allocating
memory at the runtime. But, malloc() and new have different syntax. The main difference
between the malloc() and new is that the new is an operator while malloc() is a standard library
function that is predefined in a stdlib header file.
What is new?
The new is a memory allocation operator, which is used to allocate the memory at the runtime.
The memory initialized by the new operator is allocated in a heap. It returns the starting address
of the memory, which gets assigned to the variable. The functionality of the new operator in C+
+ is similar to the malloc() function, which was used in the C programming language. C++ is
compatible with the malloc() function also, but the new operator is mostly used because of its
advantages.
Syntax of new operator
type variable = new type(parameter_list);
In the above syntax
type: It defines the datatype of the variable for which the memory is allocated by the new
operator.
variable: It is the name of the variable that points to the memory.
parameter_list: It is the list of values that are initialized to a variable.
The new operator does not use the sizeof() operator to allocate the memory. It also does not use
the resize as the new operator allocates sufficient memory for an object. It is a construct that calls
the constructor at the time of declaration to initialize an object.
As we know that the new operator allocates the memory in a heap; if the memory is not available
in a heap and the new operator tries to allocate the memory, then the exception is thrown. If our
code is not able to handle the exception, then the program will be terminated abnormally.
Let's understand the new operator through an example.
#include <iostream>
using namespace std;
int main()
{
int *ptr; // integer pointer variable declaration
ptr=new int; // allocating memory to the pointer variable ptr.
std::cout << "Enter the number : " << std::endl;
std::cin >>*ptr;
std::cout << "Entered number is " <<*ptr<< std::endl;
return 0;
}
Output:
What is malloc()?
A malloc() is a function that allocates memory at the runtime. This function returns the void
pointer, which means that it can be assigned to any pointer type. This void pointer can be further
typecast to get the pointer that points to the memory of a specified type.
The syntax of the malloc() function is given below:
type variable_name = (type *)malloc(sizeof(type));
where,
type: it is the datatype of the variable for which the memory has to be allocated.
variable_name: It defines the name of the variable that points to the memory.
(type*): It is used for typecasting so that we can get the pointer of a specified type that points to
the memory.
sizeof(): The sizeof() operator is used in the malloc() function to obtain the memory size
required for the allocation.
Note: The malloc() function returns the void pointer, so typecasting is required to assign a
different type to the pointer. The sizeof() operator is required in the malloc() function as
the malloc() function returns the raw memory, so the sizeof() operator will tell the malloc()
function how much memory is required for the allocation.
If the sufficient memory is not available, then the memory can be resized using realloc()
function. As we know that all the dynamic memory requirements are fulfilled using heap
memory, so malloc() function also allocates the memory in a heap and returns the pointer to it.
The heap memory is very limited, so when our code starts execution, it marks the memory in use,
and when our code completes its task, then it frees the memory by using the free() function. If
the sufficient memory is not available, and our code tries to access the memory, then the malloc()
function returns the NULL pointer. The memory which is allocated by the malloc() function can
be deallocated by using the free() function.
Let's understand through an example.
#include <iostream>
#include<stdlib.h>
using namespace std;
int main()
{
int len; // variable declaration
std::cout << "Enter the count of numbers :" << std::endl;
std::cin >> len;
int *ptr; // pointer variable declaration
ptr=(int*) malloc(sizeof(int)*len); // allocating memory to the poiner variable
for(int i=0;i<len;i++)
{
std::cout << "Enter a number : " << std::endl;
std::cin >> *(ptr+i);
}
std::cout << "Entered elements are : " << std::endl;
for(int i=0;i<len;i++)
{
std::cout << *(ptr+i) << std::endl;
}
free(ptr);
return 0;
}
Output:

If we do not use the free() function at the correct place, then it can lead to the cause of the
dangling pointer. Let's understand this scenario through an example.
#include <iostream>
#include<stdlib.h>
using namespace std;
int *func()
{
int *p;
p=(int*) malloc(sizeof(int));
free(p);
return p;
}
int main()
{

int *ptr;
ptr=func();
free(ptr);
return 0;
}
In the above code, we are calling the func() function. The func() function returns the integer
pointer. Inside the func() function, we have declared a *p pointer, and the memory is allocated to
this pointer variable using malloc() function. In this case, we are returning the pointer whose
memory is already released. The ptr is a dangling pointer as it is pointing to the released memory
location. Or we can say ptr is referring to that memory which is not pointed by the pointer.
Till now, we get to know about the new operator and the malloc() function. Now, we will see the
differences between the new operator and the malloc() function.
Differences between the malloc() and new

The new operator constructs an object, i.e., it calls the constructor to initialize an object
while malloc() function does not call the constructor. The new operator invokes the constructor,
and the delete operator invokes the destructor to destroy the object. This is the biggest difference
between the malloc() and new.
The new is an operator, while malloc() is a predefined function in the stdlib header file.
The operator new can be overloaded while the malloc() function cannot be overloaded.
If the sufficient memory is not available in a heap, then the new operator will throw an exception
while the malloc() function returns a NULL pointer.
In the new operator, we need to specify the number of objects to be allocated while in malloc()
function, we need to specify the number of bytes to be allocated.
In the case of a new operator, we have to use the delete operator to deallocate the memory. But
in the case of malloc() function, we have to use the free() function to deallocate the memory.
Syntax of new operator
type reference_variable = new type name;
where,
type: It defines the data type of the reference variable.
reference_variable: It is the name of the pointer variable.
new: It is an operator used for allocating the memory.
type name: It can be any basic data type.
For example,
int *p;
p = new int;
In the above statements, we are declaring an integer pointer variable. The statement p = new
int; allocates the memory space for an integer variable.
Syntax of malloc() is given below:
int *ptr = (data_type*) malloc(sizeof(data_type));
ptr: It is a pointer variable.
data_type: It can be any basic data type.
For example,
int *p;
p = (int *) malloc(sizeof(int))
The above statement will allocate the memory for an integer variable in a heap, and then stores
the address of the reserved memory in 'p' variable.
On the other hand, the memory allocated using malloc() function can be deallocated using the
free() function.
Once the memory is allocated using the new operator, then it cannot be resized. On the other
hand, the memory is allocated using malloc() function; then, it can be reallocated using realloc()
function.
The execution time of new is less than the malloc() function as new is a construct, and malloc is
a function.
The new operator does not return the separate pointer variable; it returns the address of the newly
created object. On the other hand, the malloc() function returns the void pointer which can be
further typecast in a specified type.
free vs delete in C++
In this topic, we are going to learn about the free() function and delete operator in C++.
free() function
The free() function is used in C++ to de-allocate the memory dynamically. It is basically a
library function used in C++, and it is defined in stdlib.h header file. This library function is
used when the pointers either pointing to the memory allocated using malloc() function or Null
pointer.
Syntax of free() function
Suppose we have declared a pointer 'ptr', and now, we want to de-allocate its memory:
free(ptr);
The above syntax would de-allocate the memory of the pointer variable 'ptr'.
free() parameters
In the above syntax, ptr is a parameter inside the free() function. The ptr is a pointer pointing to
the memory block allocated using malloc(), calloc() or realloc function. This pointer can also be
null or a pointer allocated using malloc but not pointing to any other memory block.
If the pointer is null, then the free() function will not do anything.
If the pointer is allocated using malloc, calloc, or realloc, but not pointing to any memory block
then this function will cause undefined behavior.
free() Return Value
The free() function does not return any value. Its main function is to free the memory.
Let's understand through an example.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int *ptr;
ptr = (int*) malloc(5*sizeof(int));
cout << "Enter 5 integer" << endl;

for (int i=0; i<5; i++)


{
// *(ptr+i) can be replaced by ptr[i]
cin >>ptr[i];
}
cout << endl << "User entered value"<< endl;
for (int i=0; i<5; i++)
{
cout <<*(ptr+i) << " ";
}
free(ptr);

/* prints a garbage value after ptr is free */


cout << "Garbage Value" << endl;

for (int i=0; i<5; i++)


{
cout << *(ptr+i)<< " ";
}
return 0;
}

The above code shows how free() function works with malloc(). First, we declare integer pointer
*ptr, and then we allocate the memory to this pointer variable by using malloc() function. Now,
ptr is pointing to the uninitialized memory block of 5 integers. After allocating the memory, we
use the free() function to destroy this allocated memory. When we try to print the value, which is
pointed by the ptr, we get a garbage value, which means that memory is de-allocated.
Output

Let's see how free() function works with a calloc.


#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
float *ptr; // float pointer declaration
ptr=(float*)calloc(1,sizeof(float));
*ptr=6.7;
std::cout << "The value of *ptr before applying the free() function : " <<*ptr<< std::endl;
free(ptr);
std::cout << "The value of *ptr after applying the free() function :" <<*ptr<< std::endl;
return 0;
}

In the above example, we can observe that free() function works with a calloc(). We use the
calloc() function to allocate the memory block to the float pointer ptr. We have assigned a
memory block to the ptr that can have a single float type value.
Output:

Let's look at another example.


#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int *ptr1=NULL;
int *ptr2;
int x=9;
ptr2=&x;
if(ptr1)
{
std::cout << "Pointer is not Null" << std::endl;
}
else
{
cout<<"Ponter is NULL";
}
free(ptr1);
//free(ptr2); // If this statement is executed, then it gives a runtime error.
return 0;
}

The above code shows how free() function works with a NULL pointer. We have declared two
pointers, i.e., ptr1 and ptr2. We assign a NULL value to the pointer ptr1 and the address of x
variable to pointer ptr2. When we apply the free(ptr1) function to the ptr1, then the memory
block assigned to the ptr is successfully freed. The statement free(ptr2) shows a runtime error as
the memory block assigned to the ptr2 is not allocated using malloc or calloc function.
Output

Delete operator
It is an operator used in C++ programming language, and it is used to de-allocate the memory
dynamically. This operator is mainly used either for those pointers which are allocated using a
new operator or NULL pointer.
Syntax
delete pointer_name
For example, if we allocate the memory to the pointer using the new operator, and now we want
to delete it. To delete the pointer, we use the following statement:
delete p;
To delete the array, we use the statement as given below:
delete [] p;
Some important points related to delete operator are:
It is either used to delete the array or non-array objects which are allocated by using the new
keyword.
To delete the array or non-array object, we use delete[] and delete operator, respectively.
The new keyword allocated the memory in a heap; therefore, we can say that the delete operator
always de-allocates the memory from the heap
It does not destroy the pointer, but the value or the memory block, which is pointed by the
pointer is destroyed.
Let's look at the simple example of a delete operator.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int *ptr;
ptr=new int;
*ptr=68;
std::cout << "The value of p is : " <<*ptr<< std::endl;
delete ptr;
std::cout <<"The value after delete is : " <<*ptr<< std::endl;
return 0;
}
In the above code, we use the new operator to allocate the memory, so we use the delete ptr
operator to destroy the memory block, which is pointed by the pointer ptr.
Output

Let's see how delete works with an array of objects.


#include <iostream>
using namespace std;
int main()
{
int *ptr=new int[5]; // memory allocation using new operator.
std::cout << "Enter 5 integers:" << std::endl;
for(int i=1;i<=5;i++)
{
cin>>ptr[i];
}
std::cout << "Entered values are:" << std::endl;
for(int i=1;i<=5;i++)
{
cout<<*(ptr+i)<<endl;
}
delete[] ptr; // deleting the memory block pointed by the ptr.
std::cout << "After delete, the garbage value:" << std::endl;
for(int i=1;i<=5;i++)
{
cout<<*(ptr+i)<<endl;
}
return 0;
}
Output

Differences between delete and free()


The following are the differences between delete and free() in C++ are:
The delete is an operator that de-allocates the memory dynamically while the free() is a function
that destroys the memory at the runtime.
The delete operator is used to delete the pointer, which is either allocated using new operator or a
NULL pointer, whereas the free() function is used to delete the pointer that is either allocated
using malloc(), calloc() or realloc() function or NULL pointer.
When the delete operator destroys the allocated memory, then it calls the destructor of the class
in C++, whereas the free() function does not call the destructor; it only frees the memory from
the heap.
The delete() operator is faster than the free() function.
C++ Polymorphism
The word “polymorphism” means having many forms. In simple words, we can define
polymorphism as the ability of a message to be displayed in more than one form. A real-life
example of polymorphism is a person who at the same time can have different characteristics.
A man at the same time is a father, a husband, and an employee. So the same person exhibits
different behavior in different situations. This is called polymorphism. Polymorphism is
considered one of the important features of Object-Oriented Programming.
Types of Polymorphism
Compile-time Polymorphism
Runtime Polymorphism

Types of Polymorphism
1. Compile-Time Polymorphism
This type of polymorphism is achieved by function overloading or operator overloading.
A. Function Overloading
When there are multiple functions with the same name but different parameters, then the
functions are said to be overloaded, hence this is known as Function Overloading. Functions
can be overloaded by changing the number of arguments or/and changing the type of
arguments. In simple terms, it is a feature of object-oriented programming providing many
functions that have the same name but distinct parameters when numerous tasks are listed
under one function name. There are certain Rules of Function Overloading that should be
followed while overloading a function.
Below is the C++ program to show function overloading or compile-time polymorphism:

// C++ program to demonstrate


// function overloading or
// Compile-time Polymorphism
#include <bits/stdc++.h>

using namespace std;


class Geeks {
public:
// Function with 1 int parameter
void func(int x)
{
cout << "value of x is " << x << endl;
}

// Function with same name but


// 1 double parameter
void func(double x)
{
cout << "value of x is " << x << endl;
}

// Function with same name and


// 2 int parameters
void func(int x, int y)
{
cout << "value of x and y is " << x << ", " << y
<< endl;
}
};

// Driver code
int main()
{
Geeks obj1;

// Function being called depends


// on the parameters passed
// func() is called with int value
[Link](7);

// func() is called with double value


[Link](9.132);

// func() is called with 2 int values


[Link](85, 64);
return 0;
}

Output
value of x is 7
value of x is 9.132
value of x and y is 85, 64
Explanation: In the above example, a single function named function func() acts differently
in three different situations, which is a property of polymorphism. To know more about this,
you can refer to the article – Function Overloading in C++ .
B. Operator Overloading
C++ has the ability to provide the operators with a special meaning for a data type, this ability
is known as operator overloading. For example, we can make use of the addition operator (+)
for string class to concatenate two strings. We know that the task of this operator is to add two
operands. So a single operator ‘+’, when placed between integer operands, adds them and
when placed between string operands, concatenates them.
Below is the C++ program to demonstrate operator overloading:

// C++ program to demonstrate


// Operator Overloading or
// Compile-Time Polymorphism
#include <iostream>
using namespace std;

class Complex {
private:
int real, imag;

public:
Complex(int r = 0, int i = 0)
{
real = r;
imag = i;
}

// This is automatically called


// when '+' is used with between
// two Complex objects
Complex operator+(Complex const& obj)
{
Complex res;
[Link] = real + [Link];
[Link] = imag + [Link];
return res;
}
void print() { cout << real << " + i" << imag << endl; }
};

// Driver code
int main()
{
Complex c1(10, 5), c2(2, 4);

// An example call to "operator+"


Complex c3 = c1 + c2;
[Link]();
}

Output
12 + i9
Explanation: In the above example, the operator ‘+’ is overloaded. Usually, this operator is
used to add two numbers (integers or floating point numbers), but here the operator is made to
perform the addition of two imaginary or complex numbers. To know more about this one,
refer to the article – Operator Overloading .
2. Runtime Polymorphism
This type of polymorphism is achieved by Function Overriding. Late binding and dynamic
polymorphism are other names for runtime polymorphism. The function call is resolved at
runtime in runtime polymorphism . In contrast, with compile time polymorphism, the compiler
determines which function call to bind to the object after deducing it at runtime.
A. Function Overriding
Function Overriding occurs when a derived class has a definition for one of the member
functions of the base class. That base function is said to be overridden.
Function overriding Explanation

Runtime Polymorphism with Data Members


Runtime Polymorphism cannot be achieved by data members in C++. Let’s see an example
where we are accessing the field by reference variable of parent class which refers to the
instance of the derived class.

// C++ program for function overriding with data members


#include <bits/stdc++.h>
using namespace std;

// base class declaration.


class Animal {
public:
string color = "Black";
};

// inheriting Animal class.


class Dog : public Animal {
public:
string color = "Grey";
};

// Driver code
int main(void)
{
Animal d = Dog(); // accessing the field by reference
// variable which refers to derived
cout << [Link];
}

Output
Black

We can see that the parent class reference will always refer to the data member of the parent
class.

B. Virtual Function

A virtual function is a member function that is declared in the base class using the keyword
virtual and is re-defined (Overridden) in the derived class.
Some Key Points About Virtual Functions:
Virtual functions are Dynamic in nature.
They are defined by inserting the keyword “virtual” inside a base class and are always
declared with a base class and overridden in a child class
A virtual function is called during Runtime
Below is the C++ program to demonstrate virtual function:
// C++ Program to demonstrate
// the Virtual Function
#include <iostream>
using namespace std;

// Declaring a Base class


class GFG_Base {

public:
// virtual function
virtual void display()
{
cout << "Called virtual Base Class function"
<< "\n\n";
}

void print()
{
cout << "Called GFG_Base print function"
<< "\n\n";
}
};

// Declaring a Child Class


class GFG_Child : public GFG_Base {

public:
void display()
{
cout << "Called GFG_Child Display Function"
<< "\n\n";
}

void print()
{
cout << "Called GFG_Child print Function"
<< "\n\n";
}
};

// Driver code
int main()
{
// Create a reference of class GFG_Base
GFG_Base* base;
GFG_Child child;

base = &child;

// This will call the virtual function


base->GFG_Base::display();

// this will call the non-virtual function


base->print();
}

Output
Called virtual Base Class function

Called GFG_Base print function


Example 2:

// C++ program for virtual function overriding


#include <bits/stdc++.h>
using namespace std;

class base {
public:
virtual void print()
{
cout << "print base class" << endl;
}

void show() { cout << "show base class" << endl; }


};

class derived : public base {


public:
// print () is already virtual function in
// derived class, we could also declared as
// virtual void print () explicitly
void print() { cout << "print derived class" << endl; }

void show() { cout << "show derived class" << endl; }


};

// Driver code
int main()
{
base* bptr;
derived d;
bptr = &d;

// Virtual function, binded at


// runtime (Runtime polymorphism)
bptr->print();

// Non-virtual function, binded


// at compile time
bptr->show();

return 0;
}

Output
print derived class
show base class

Function Overriding in C++


A function is a block of statements that together performs a specific task by taking some input
and producing a particular output. Function overriding in C++ is termed as the redefinition
of base class function in its derived class with the same signature i.e. return type and
parameters. It falls under the category of Runtime Polymorphism.
Real-Life Example of Function Overriding
The best Real-life example of this concept is the Constitution of India. India took the political
code, structure, procedures, powers, and duties of government institutions and set out
fundamental rights, directive principles, and the duties of citizens of other countries and
implemented them on its own; making it the biggest constitution in the world.
Another Development real-life example could be the relationship between RBI(The Reserve
Bank of India) and Other state banks like SBI, PNB, ICICI, etc. Where the RBI passes the
same regulatory function and others follow it as it is.
Function Overriding
Syntax:
class Parent{

access_modifier:

// overridden function

return_type name_of_the_function(){}

};

class child : public Parent {

access_modifier:

// overriding function

return_type name_of_the_function(){}

};

}
Example:

// C++ program to demonstrate function overriding

#include <iostream>
using namespace std;
class Parent {
public:
void GeeksforGeeks_Print()
{
cout << "Base Function" << endl;
}
};

class Child : public Parent {


public:
void GeeksforGeeks_Print()
{
cout << "Derived Function" << endl;
}
};

int main()
{
Child Child_Derived;
Child_Derived.GeeksforGeeks_Print();
return 0;
}

Output
Derived Function
Variations in Function Overriding
1. Call Overridden Function From Derived Class

// C++ program to demonstrate function overriding


// by calling the overridden function
// of a member function from the child class

#include <iostream>
using namespace std;

class Parent {
public:
void GeeksforGeeks_Print()
{
cout << "Base Function" << endl;
}
};

class Child : public Parent {


public:
void GeeksforGeeks_Print()
{
cout << "Derived Function" << endl;

// call of overridden function


Parent::GeeksforGeeks_Print();
}
};

int main()
{
Child Child_Derived;
Child_Derived.GeeksforGeeks_Print();
return 0;
}

Output
Derived Function
Base Function
The output of Call Overridden Function From Derived Class
2. Call Overridden Function Using Pointer

// C++ program to access overridden function using pointer


// of Base type that points to an object of Derived class
#include <iostream>
using namespace std;

class Parent {
public:
void GeeksforGeeks()
{
cout << "Base Function" << endl;
}
};

class Child : public Parent {


public:
void GeeksforGeeks()
{
cout << "Derived Function" << endl;
}
};

int main()
{
Child Child_Derived;

// pointer of Parent type that points to derived1


Parent* ptr = &Child_Derived;

// call function of Base class using ptr


ptr->GeeksforGeeks();

return 0;
}

Output
Base Function
3. Access of Overridden Function to the Base Class

// C++ program to access overridden function


// in main() using the scope resolution operator ::

#include <iostream>
using namespace std;
class Parent {
public:
void GeeksforGeeks()
{
cout << "Base Function" << endl;
}
};

class Child : public Parent {


public:
void GeeksforGeeks()
{
cout << "Derived Function" << endl;
}
};

int main()
{
Child Child_Derived;
Child_Derived.GeeksforGeeks();

// access GeeksforGeeks() function of the Base class


Child_Derived.Parent::GeeksforGeeks();
return 0;
}

Output
Derived Function
Base Function

Access of Overridden Function to the Base Class


4. Access to Overridden Function

// C++ Program Demonstrating


// Accessing of Overridden Function
#include <iostream>
using namespace std;

// defining of the Parent class


class Parent

{
public:
// defining the overridden function
void GeeksforGeeks_Print()
{
cout << "I am the Parent class function" << endl;
}
};

// defining of the derived class


class Child : public Parent

{
public:
// defining of the overriding function
void GeeksforGeeks_Print()
{
cout << "I am the Child class function" << endl;
}
};

int main()
{
// create instances of the derived class
Child GFG1, GFG2;

// call the overriding function


GFG1.GeeksforGeeks_Print();

// call the overridden function of the Base class


[Link]::GeeksforGeeks_Print();
return 0;
}

Output
I am the Child class function
I am the Parent class function
Function Overloading Vs Function Overriding
Function Overloading Function Overriding

It falls under Compile-Time polymorphism It falls under Runtime Polymorphism

A function can be overloaded multiple times A function cannot be overridden multiple


as it is resolved at Compile time times as it is resolved at Run time
Function Overloading Function Overriding

Can be executed without inheritance Cannot be executed without inheritance

They are in the same scope They are of different scopes.

C++ Files
In C++ programming we are using the iostream standard library, it
provides cin and cout methods for reading from input and writing to output respectively.

To read and write from a file we are using the standard C++ library called fstream. Let us see
the data types define in fstream library is:

Data Type Description

fstream It is used to create files, write information to files, and read information from files.

ifstream It is used to read information from files.

ofstream It is used to create files and write information to the files.

C++ FileStream example: writing to a file

Let's see the simple example of writing to a text file [Link] using C++ FileStream
programming.

1. #include <iostream>
2. #include <fstream>
3. using namespace std;
4. int main () {
5. ofstream filestream("[Link]");
6. if (filestream.is_open())
7. {
8. filestream << "Welcome to javaTpoint.\n";
9. filestream << "C++ Tutorial.\n";
10. [Link]();
11. }
12. else cout <<"File opening is fail.";
13. return 0;
14. }

Output:

The content of a text file [Link] is set with the data:


Welcome to javaTpoint.
C++ Tutorial.

C++ FileStream example: reading from a file

Let's see the simple example of reading from a text file [Link] using C++ FileStream
programming.

1. #include <iostream>
2. #include <fstream>
3. using namespace std;
4. int main () {
5. string srg;
6. ifstream filestream("[Link]");
7. if (filestream.is_open())
8. {
9. while ( getline (filestream,srg) )
10. {
11. cout << srg <<endl;
12. }
13. [Link]();
14. }
15. else {
16. cout << "File opening is fail."<<endl;
17. }
18. return 0;
19. }
Note: Before running the code a text file named as "[Link]" is need to be created and the
content of a text file is given below:
Welcome to javaTpoint.
C++ Tutorial.

Output:

Welcome to javaTpoint.
C++ Tutorial.

C++ Read and Write Example

Let's see the simple example of writing the data to a text file [Link] and then reading the data
from the file using C++ FileStream programming.

1. #include <fstream>
2. #include <iostream>
3. using namespace std;
4. int main () {
5. char input[75];
6. ofstream os;
7. [Link]("[Link]");
8. cout <<"Writing to a text file:" << endl;
9. cout << "Please Enter your name: ";
10. [Link](input, 100);
11. os << input << endl;
12. cout << "Please Enter your age: ";
13. cin >> input;
14. [Link]();
15. os << input << endl;
16. [Link]();
17. ifstream is;
18. string line;
19. [Link]("[Link]");
20. cout << "Reading from a text file:" << endl;
21. while (getline (is,line))
22. {
23. cout << line << endl;
24. }
25. [Link]();
26. return 0;
27. }

Output:

Writing to a text file:


Please Enter your name: Nakul Jain
Please Enter your age: 22
Reading from a text file: Nakul Jain
22
C++ getline()

The cin is an object which is used to take input from the user but does not allow to take the input
in multiple lines. To accept the multiple lines, we use the getline() function. It is a pre-defined
function defined in a <string.h> header file used to accept a line or a string from the input
stream until the delimiting character is encountered.

Syntax of getline() function:

There are two ways of representing a function:

o The first way of declaring is to pass three parameters.

1. istream& getline( istream& is, string& str, char delim );


The above syntax contains three parameters, i.e., is, str, and delim.

Where,

is: It is an object of the istream class that defines from where to read the input stream.

str: It is a string object in which string is stored.

delim: It is the delimiting character.

Return value

This function returns the input stream object, which is passed as a parameter to the function.

o The second way of declaring is to pass two parameters.

1. istream& getline( istream& is, string& str );

The above syntax contains two parameters, i.e., is and str. This syntax is almost similar to the
above syntax; the only difference is that it does not have any delimiting character.

Where,

is: It is an object of the istream class that defines from where to read the input stream.

str: It is a string object in which string is stored.

Return value

This function also returns the input stream, which is passed as a parameter to the function.

Let's understand through an example.

First, we will look at an example where we take the user input without using getline() function.

1. #include <iostream>
2. #include<string.h>
3. using namespace std;
4. int main()
5. {
6. string name; // variable declaration
7. std::cout << "Enter your name :" << std::endl;
8. cin>>name;
9. cout<<"\nHello "<<name;
10. return 0;
11. }

In the above code, we take the user input by using the statement cin>>name, i.e., we have not
used the getline() function.

Output

Enter your name :


John Miller
Hello John

In the above output, we gave the name 'John Miller' as user input, but only 'John' was displayed.
Therefore, we conclude that cin does not consider the character when the space character is
encountered.

Let's resolve the above problem by using getline() function.

1. #include <iostream>
2. #include<string.h>
3. using namespace std;
4. int main()
5. {
6. string name; // variable declaration.
7. std::cout << "Enter your name :" << std::endl;
8. getline(cin,name); // implementing a getline() function
9. cout<<"\nHello "<<name;
10. return 0;}

In the above code, we have used the getline() function to accept the character even when the
space character is encountered.

Output

Enter your name :


John Miller
Hello John Miller

In the above output, we can observe that both the words, i.e., John and Miller, are displayed,
which means that the getline() function considers the character after the space character also.

When we do not want to read the character after space then we use the following code:

1. #include <iostream>
2. #include<string.h>
3. using namespace std;
4. int main()
5. {
6. string profile; // variable declaration
7. std::cout << "Enter your profile :" << std::endl;
8. getline(cin,profile,' '); // implementing getline() function with a delimiting character.
9. cout<<"\nProfile is :"<<profile;
10. }

In the above code, we take the user input by using getline() function, but this time we also add
the delimiting character('') in a third parameter. Here, delimiting character is a space character,
means the character that appears after space will not be considered.

Output

Enter your profile :


Software Developer
Profile is: Software

Getline Character Array

We can also define the getline() function for character array, but its syntax is different from the
previous one.

Syntax

1. istream& getline(char* , int size);

In the above syntax, there are two parameters; one is char*, and the other is size.

Where,
char*: It is a character pointer that points to the array.

Size: It acts as a delimiter that defines the size of the array means input cannot cross this size.

Let's understand through an example.

1. #include <iostream>
2. #include<string.h>
3. using namespace std;
4. int main()
5. {
6. char fruits[50]; // array declaration
7. cout<< "Enter your favorite fruit: ";
8. [Link](fruits, 50); // implementing getline() function
9. std::cout << "\nYour favorite fruit is :"<<fruits << std::endl;
10. return 0;
11. }

Output

Enter your favorite fruit: Watermelon


Your favorite fruit is: Watermelon

C++ Exception Handling


Exception Handling in C++ is a process to handle runtime errors. We perform exception
handling so the normal flow of the application can be maintained even after runtime errors.

In C++, exception is an event or object which is thrown at runtime. All exceptions are derived
from std::exception class. It is a runtime error which can be handled. If we don't handle the
exception, it prints exception message and terminates the program.

Advantage

It maintains the normal flow of the application. In such case, rest of the code is executed even
after exception.
C++ Exception Classes

In C++ standard exceptions are defined in <exception> class that we can use inside our
programs. The arrangement of parent-child class hierarchy is shown below:

All the exception classes in C++ are derived from std::exception class. Let's see the list of C++
common exception classes.

Exception Description

std::exception It is an exception and parent class of all standard C++ exceptions.


std::logic_failure It is an exception that can be detected by reading a code.

std::runtime_error It is an exception that cannot be detected by reading a code.

std::bad_exception It is used to handle the unexpected exceptions in a c++ program.

std::bad_cast This exception is generally be thrown by dynamic_cast.

std::bad_typeid This exception is generally be thrown by typeid.

std::bad_alloc This exception is generally be thrown by new.

C++ Exception Handling Keywords

In C++, we use 3 keywords to perform exception handling:

o try

o catch, and

o throw

C++ try/catch

In C++ programming, exception handling is performed using try/catch statement. The C++ try
block is used to place the code that may occur exception. The catch block is used to handle the
exception.

C++ example without try/catch

1. #include <iostream>
2. using namespace std;
3. float division(int x, int y) {
4. return (x/y);
5. }
6. int main () {
7. int i = 50;
8. int j = 0;
9. float k = 0;
10. k = division(i, j);
11. cout << k << endl;
12. return 0;
13. }

Output:

Floating point exception (core dumped)

C++ try/catch example

1. #include <iostream>
2. using namespace std;
3. float division(int x, int y) {
4. if( y == 0 ) {
5. throw "Attempted to divide by zero!";
6. }
7. return (x/y);
8. }
9. int main () {
10. int i = 25;
11. int j = 0;
12. float k = 0;
13. try {
14. k = division(i, j);
15. cout << k << endl;
16. }catch (const char* e) {
17. cerr << e << endl;
18. }
19. return 0;
20. }

Output:

Attempted to divide by zero!


C++ User-Defined Exceptions

The new exception can be defined by overriding and inheriting exception class functionality.

C++ user-defined exception example

Let's see the simple example of user-defined exception in which std::exception class is used to
define the exception.

1. #include <iostream>
2. #include <exception>
3. using namespace std;
4. class MyException : public exception{
5. public:
6. const char * what() const throw()
7. {
8. return "Attempted to divide by zero!\n";
9. }
10. };
11. int main()
12. {
13. try
14. {
15. int x, y;
16. cout << "Enter the two numbers : \n";
17. cin >> x >> y;
18. if (y == 0)
19. {
20. MyException z;
21. throw z;
22. }
23. else
24. {
25. cout << "x / y = " << x/y << endl;
26. }
27. }
28. catch(exception& e)
29. {
30. cout << [Link]();
31. }
32. }

Output:

Enter the two numbers :


10
2
x/y=5

Output:

Enter the two numbers :


10
0
Attempted to divide by zero!
-->

Note: In above example what() is a public method provided by the exception class. It is used to
return the cause of an exception.

Strings in C++
C++ strings are sequences of characters stored in a char array. Strings are used to store words
and text. They are also used to store data, such as numbers and other types of information.
Strings in C++ can be defined either using the std::string class or the C-style character
arrays.

1. C Style Strings
These strings are stored as the plain old array of characters terminated by a null character ‘\
0’. They are the type of strings that C++ inherited from C language.
Syntax:
char str[] = "GeeksforGeeks";
Example:
C++

// C++ Program to demonstrate strings


#include <iostream>
using namespace std;

int main()
{

char s[] = "GeeksforGeeks";


cout << s << endl;
return 0;
}

Output
GeeksforGeeks
2. std::string Class
These are the new types of strings that are introduced in C++ as std::string class defined
inside <string> header file. This provides many advantages over conventional C-style strings
such as dynamic size, member functions, etc.
Syntax:
std::string str("GeeksforGeeks");
Example:
C++

// C++ program to create std::string objects


#include <iostream>
using namespace std;

int main()
{

string str("GeeksforGeeks");
cout << str;
return 0;
}
Output
GeeksforGeeks
One more way we can make strings that have the same character repeating again and again.
Syntax:
std::string str(number,character);
Example:
C++

#include <iostream>
using namespace std;

int main()
{
string str(5, 'g');
cout << str;
return 0;
}

Output:
ggggg

Ways to Define a String in C++


Strings can be defined in several ways in C++. Strings can be accessed from the standard
library using the string class. Character arrays can also be used to define strings. String
provides a rich set of features, such as searching and manipulating, which are commonly used
methods. Despite being less advanced than the string class, this method is still widely used, as
it is more efficient and easier to use. Ways to define a string in C++ are:
Using String keyword
Using C-style strings
1. Using string Keyword
It is more convenient to define a string with the string keyword instead of using the array
keyword because it is easy to write and understand.
Syntax:
string s = "GeeksforGeeks";
string s("GeeksforGeeks");
Example:

// C++ Program to demonstrate use of string keyword


#include <iostream>
using namespace std;

int main()
{

string s = "GeeksforGeeks";
string str("GeeksforGeeks");
cout << "s = " << s << endl;
cout << "str = " << str << endl;

return 0;
}

Output
s = GeeksforGeeks
str = GeeksforGeeks
2. Using C-style strings
Using C-style string libraries functions such as strcpy(), strcmp(), and strcat() to define
strings. This method is more complex and not as widely used as the other two, but it can be
useful when dealing with legacy code or when you need performance.
char s[] = {'g', 'f', 'g', '\0'};
char s[4] = {'g', 'f', 'g', '\0'};
char s[4] = "gfg";
char s[] = "gfg";
Example:
C++

// C++ Program to demonstrate C-style string declaration


#include <iostream>
using namespace std;

int main()
{

char s1[] = { 'g', 'f', 'g', '\0' };


char s2[4] = { 'g', 'f', 'g', '\0' };
char s3[4] = "gfg";
char s4[] = "gfg";

cout << "s1 = " << s1 << endl;


cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s4 = " << s4 << endl;

return 0;
}

Output
s1 = gfg
s2 = gfg
s3 = gfg
s4 = gfg
Another example of C-style string:
C++

#include <iostream>
using namespace std;

int main()
{
string S = "Geeeks for Geeks";
cout << "Your string is= ";
cout << S << endl;

return 0;
}

Output
Your string is= Geeeks for Geeks
How to Take String Input in C++
String input means accepting a string from a user. In C++. We have different types of taking
input from the user which depend on the string. The most common way is to take input
with cin keyword with the extraction operator (>>) in C++. Methods to take a string as input
are:
cin
getline
stringstream
1. Using Cin
The simplest way to take string input is to use the cin command along with the stream
extraction operator (>>).
Syntax:
cin>>s;
Example:
C++

// C++ Program to demonstrate string input using cin


#include <iostream>
using namespace std;

int main() {

string s;

cout<<"Enter String"<<endl;
cin>>s;

cout<<"String is: "<<s<<endl;


return 0;
}

Output
Enter String
String is:
Output:
Enter String
GeeksforGeeks
String is: GeeksforGeeks
2. Using getline
The getline() function in C++ is used to read a string from an input stream. It is declared in
the <string> header file.
Syntax:
getline(cin,s);
Example:
C++

// C++ Program to demonstrate use of getline function


#include <iostream>
using namespace std;

int main()
{

string s;
cout << "Enter String" << endl;
getline(cin, s);
cout << "String is: " << s << endl;
return 0;
}

Output
Enter String
String is:
Output:
Enter String
GeeksforGeeks
String is: GeeksforGeeks
3. Using stringstream
The stringstream class in C++ is used to take multiple strings as input at once.
Syntax:
stringstream stringstream_object(string_name);
Example:
C++
// C++ Program to demonstrate use of stringstream object
#include <iostream>
#include <sstream>
#include<string>

using namespace std;

int main()
{

string s = " GeeksforGeeks to the Moon ";


stringstream obj(s);
// string to store words individually
string temp;
// >> operator will read from the stringstream object
while (obj >> temp) {
cout << temp << endl;
}
return 0;
}

Output
GeeksforGeeks
to
the
Moon
How to Pass Strings to Functions?
In the same way that we pass an array to a function, strings in C++ can be passed to functions
as character arrays. Here is an example program:
Example:
C++

// C++ Program to print string using function


#include <iostream>
using namespace std;

void print_string(string s)
{
cout << "Passed String is: " << s << endl;
return;
}

int main()
{
string s = "GeeksforGeeks";
print_string(s);

return 0;
}

Output
Passed String is: GeeksforGeeks
Pointers and Strings
Pointers in C++ are symbolic representations of addresses. They enable programs to simulate
call-by-reference as well as to create and manipulate dynamic data structures. By using
pointers we can get the first character of the string, which is the starting address of the string.
As shown below, the given string can be accessed and printed through the pointers.
Example:
C++

// C++ Program to print string using pointers


#include <iostream>
using namespace std;

int main()
{

string s = "Geeksforgeeks";

// pointer variable declared to store the starting


// address of the string
char* p = &s[0];

// this loop will execute and print the character till


// the character value is null this loop will execute and
// print the characters

while (*p != '\0') {


cout << *p;
p++;
}
cout << endl;

return 0;
}

Output
Geeksforgeeks
Difference between String and Character array in C++
The main difference between a string and a character array is that strings are immutable, while
character arrays are not.
String Character Array

Strings define objects that can be represented The null character terminates a character
as string streams. array of characters.

The threat of
No Array decay occurs in strings as strings are
array decay
represented as objects.
is present in the case of the character array

A string class provides numerous functions for Character arrays do not offer inbuilt
manipulating strings. functions to manipulate strings.

The size of the character array has to be


Memory is allocated dynamically.
allocated statically.

Know more about the difference between strings and character arrays in C++
C++ String Functions
C++ provides some inbuilt functions which are used for string manipulation, such as the
strcpy() and strcat() functions for copying and concatenating strings. Some of them are:
Function Description

length() This function returns the length of the string.

swap() This function is used to swap the values of 2 strings.

size() Used to find the size of string

This function is used to resize the length of the string up to the given number of
resize()
characters.

find() Used to find the string which is passed in parameters

push_back() This function is used to push the passed character at the end of the string

pop_back() This function is used to pop the last character from the string
Function Description

clear() This function is used to remove all the elements of the string.

strncmp() This function compares at most the first num bytes of both passed strings.

This function is similar to strcpy() function, except that at most n bytes of src
strncpy()
are copied

strrchr() This function locates the last occurrence of a character in the string.

This function appends a copy of the source string to the end of the destination
strcat()
string

This function is used to search for a certain substring inside a string and returns
find()
the position of the first character of the substring.

This function is used to replace each element in the range [first, last) that is
replace()
equal to old value with new value.

substr() This function is used to create a substring from a given string.

This function is used to compare two strings and returns the result in the form of
compare()
an integer.

erase() This function is used to remove a certain part of a string.

C++ Strings iterator functions

In C++ inbuilt string iterator functions provide the programmer with an easy way to modify
and traverse string elements. These functions are:
Functions Description

begin() This function returns an iterator pointing to the beginning of the string.

end() This function returns an iterator that points to the end of the string.
Functions Description

rfind() This function is used to find the string’s last occurrence.

rbegin() This function returns a reverse iterator pointing to the end of the string.

rend() This function returns a reverse iterator pointing to the beginning of the string.

cbegin() This function returns a const_iterator pointing to the beginning of the string.

cend() This function returns a const_iterator pointing to the end of the string.

crbegin() This function returns a const_reverse_iterator pointing to the end of the string.

This function returns a const_reverse_iterator pointing to the beginning of the


crend()
string.

Example:
C++

// C++ Program to demonstrate string iterator functions


#include <iostream>
using namespace std;

int main()
{
// declaring an iterator
string::iterator itr;

// declaring a reverse iterator


string::reverse_iterator rit;

string s = "GeeksforGeeks";

itr = [Link]();

cout << "Pointing to the start of the string: " << *itr<< endl;

itr = [Link]() - 1;
cout << "Pointing to the end of the string: " << *itr << endl;

rit = [Link]();
cout << "Pointing to the last character of the string: " << *rit << endl;

rit = [Link]() - 1;
cout << "Pointing to the first character of the string: " << *rit << endl;

return 0;
}

Output
Pointing to the start of the string: G
Pointing to the end of the string: s
Pointing to the last character of the string: s
Pointing to the first character of the string: G
String Capacity Functions
In C++, string capacity functions are used to manage string size and capacity. Primary
functions of capacity include:
Function Description

length() This function is used to return the size of the string

This function returns the capacity which is allocated to the string by the
capacity()
compiler

resize() This function allows us to increase or decrease the string size

shrink_to_fit() This function decreases the capacity and makes it equal to the minimum.

Example:
C++

#include <iostream>
using namespace std;

int main()
{

string s = "GeeksforGeeks";

// length function is used to print the length of the string


cout << "The length of the string is " << [Link]() << endl;

// capacity function is used to print the capacity of the string


cout << "The capacity of string is " << [Link]()<< endl;

// the [Link]() function is used to resize the string to 10 characters


[Link](10);

cout << "The string after using resize function is " << s << endl;

[Link](20);

cout << "The capacity of string before using shrink_to_fit function is "<< [Link]() << endl;

// shrink to fit function is used to reduce the capacity of the container


s.shrink_to_fit();

cout << "The capacity of string after using shrink_to_fit function is "<< [Link]() << endl;

return 0;
}

Output
The length of the string is 13
The capacity of string is 15
The string after using resize function is GeeksforGe
The capacity of string before using shrink_to_fit function is 30
The capacity of string...
In conclusion, this article explains how strings can be defied in C++ using character arrays
and string classes. The string class provides more advanced features, while the character array
provides basic features but is efficient and easy to use. In this article, we also discussed the
various methods to take input from the user.

Templates in C++
A template is a simple yet very powerful tool in C++. The simple idea is to pass the data type as
a parameter so that we don’t need to write the same code for different data types. For example, a
software company may need to sort() for different data types. Rather than writing and
maintaining multiple codes, we can write one sort() and pass the datatype as a parameter.
C++ adds two new keywords to support templates: ‘template’ and ‘type name’. The second
keyword can always be replaced by the keyword ‘class’.
How Do Templates Work?
Templates are expanded at compiler time. This is like macros. The difference is, that the
compiler does type-checking before template expansion. The idea is simple, source code contains
only function/class, but compiled code may contain multiple copies of the same function/class.
Function Templates
We write a generic function that can be used for different data types. Examples of function
templates are sort(), max(), min(), printArray().
To know more about the topic refer to Generics in C++.
Example:
C++

// C++ Program to demonstrate


// Use of template
#include <iostream>
using namespace std;

// One function works for all data types. This would work
// even for user defined types if operator '>' is overloaded
template <typename T> T myMax(T x, T y)
{
return (x > y) ? x : y;
}

int main()
{
// Call myMax for int
cout << myMax<int>(3, 7) << endl;
// call myMax for double
cout << myMax<double>(3.0, 7.0) << endl;
// call myMax for char
cout << myMax<char>('g', 'e') << endl;

return 0;
}

Output
7
7
g

Example: Implementing Bubble Sort using templates in C++


C++

// C++ Program to implement


// Bubble sort
// using template function
#include <iostream>
using namespace std;
// A template function to implement bubble sort.
// We can use this for any data type that supports
// comparison operator < and swap works for it.
template <class T> void bubbleSort(T a[], int n)
{
for (int i = 0; i < n - 1; i++)
for (int j = n - 1; i < j; j--)
if (a[j] < a[j - 1])
swap(a[j], a[j - 1]);
}

// Driver Code
int main()
{
int a[5] = { 10, 50, 30, 40, 20 };
int n = sizeof(a) / sizeof(a[0]);

// calls template function


bubbleSort<int>(a, n);

cout << " Sorted array : ";


for (int i = 0; i < n; i++)
cout << a[i] << " ";
cout << endl;

return 0;
}

Output
Sorted array : 10 20 30 40 50

Class Templates
Class templates like function templates, class templates are useful when a class defines
something that is independent of the data type. Can be useful for classes like LinkedList,
BinaryTree, Stack, Queue, Array, etc.
Example:
C++

// C++ Program to implement


// template Array class
#include <iostream>
using namespace std;

template <typename T> class Array {


private:
T* ptr;
int size;

public:
Array(T arr[], int s);
void print();
};

template <typename T> Array<T>::Array(T arr[], int s)


{
ptr = new T[s];
size = s;
for (int i = 0; i < size; i++)
ptr[i] = arr[i];
}

template <typename T> void Array<T>::print()


{
for (int i = 0; i < size; i++)
cout << " " << *(ptr + i);
cout << endl;
}

int main()
{
int arr[5] = { 1, 2, 3, 4, 5 };
Array<int> a(arr, 5);
[Link]();
return 0;
}

Output
12345

Can there be more than one argument for templates?


Yes, like normal parameters, we can pass more than one data type as arguments to templates.
The following example demonstrates the same.
Example:
C++

// C++ Program to implement


// Use of template
#include <iostream>
using namespace std;
template <class T, class U> class A {
T x;
U y;

public:
A() { cout << "Constructor Called" << endl; }
};

int main()
{
A<char, char> a;
A<int, double> b;
return 0;
}

Output
Constructor Called
Constructor Called

Can we specify a default value for template arguments?


Yes, like normal parameters, we can specify default arguments to templates. The following
example demonstrates the same.
Example:
C++

// C++ Program to implement


// Use of template
#include <iostream>
using namespace std;

template <class T, class U = char> class A {


public:
T x;
U y;
A() { cout << "Constructor Called" << endl; }
};

int main()
{
// This will call A<char, char>
A<char> a;

return 0;
}
Output
Constructor Called

What is the difference between function overloading and templates?


Both function overloading and templates are examples of polymorphism features of OOP.
Function overloading is used when multiple functions do quite similar (not identical) operations,
templates are used when multiple functions do identical operations.
What happens when there is a static member in a template class/function?
Each instance of a template contains its own static variable. See Templates and Static
variables for more details.
What is template specialization?
Template specialization allows us to have different codes for a particular data type.
See Template Specialization for more details.
Can we pass non-type parameters to templates?
We can pass non-type arguments to templates. Non-type parameters are mainly used for
specifying max or min values or any other constant value for a particular instance of a template.
The important thing to note about non-type parameters is, that they must be const. The compiler
must know the value of non-type parameters at compile time. Because the compiler needs to
create functions/classes for a specified non-type value at compile time. In the below program, if
we replace 10000 or 25 with a variable, we get a compiler error.
Example:
C++

// C++ program to demonstrate


// working of non-type parameters
// to templates in C++
#include <iostream>
using namespace std;

template <class T, int max> int arrMin(T arr[], int n)


{
int m = max;
for (int i = 0; i < n; i++)
if (arr[i] < m)
m = arr[i];

return m;
}

int main()
{
int arr1[] = { 10, 20, 15, 12 };
int n1 = sizeof(arr1) / sizeof(arr1[0]);

char arr2[] = { 1, 2, 3 };
int n2 = sizeof(arr2) / sizeof(arr2[0]);
// Second template parameter
// to arrMin must be a
// constant
cout << arrMin<int, 10000>(arr1, n1) << endl;
cout << arrMin<char, 256>(arr2, n2);

return 0;
}

Output
10
1

Here is an example of a C++ program to show different data types using a constructor and
template. We will perform a few actions
passing character value by creating an object in the main() function.
passing integer value by creating an object in the main() function.
passing float value by creating an object in the main() function.
Example:
C++

// C++ program to show different data types using a


// constructor and template.
#include <iostream>
using namespace std;

// defining a class template


template <class T> class info {
public:
// constructor of type template
info(T A)
{
cout << "\n"
<< "A = " << A
<< " size of data in bytes:" << sizeof(A);
}
// end of info()
}; // end of class

// Main Function
int main()
{
// clrscr();
// passing character value by creating an objects
info<char> p('x');

// passing integer value by creating an object


info<int> q(22);

// passing float value by creating an object


info<float> r(2.25);

return 0;
}

Output
A = x size of data in bytes:1
A = 22 size of data in bytes:4
A = 2.25 size of data in bytes:4

Template Argument Deduction


Template argument deduction automatically deduces the data type of the argument passed to the
class or function templates. This allows us to instantiate the template without explicitly
specifying the data type.
For example, consider the below function template to multiply two numbers:
template <typename t>
t multiply (t num1,t num2) { return num1*num2; }

In general, when we want to use the multiply() function for integers, we have to call it like this:
multiply<int> (25, 5);

But we can also call it:


multiply(23, 5);

We don’t explicitly specify the type ie 1,3 are integers.


The same is true for the template classes(since C++17 only). Suppose we define the template
class as:
template<typename t>
class student{
private:
t total_marks;
public:
student(t x) : total_marks(x) {}
};

If we want to create an instance of this class, we can use any of the following syntax:
student<int> stu1(23);
or
student stu2(24);
Note: It is important to note thet the template argument deduction for a classes is only available
since C++17, so if we
Example of Template Argument Deduction
The below example demonstrates how the STL vector class template deduces the data type
without being explicitly specified.
C++

// C++ Program to illustrate template arguments deduction in


// STL
#include <iostream>
#include <vector>

using namespace std;

int main()
{
// creating a vector<float> object without specifying
// type
vector v1{ 1.1, 2.0, 3.9, 4.909 };
cout << "Elements of v1 : ";
for (auto i : v1) {
cout << i << " ";
}

// creating a vector<int> object without specifying type


vector v2{ 1, 2, 3, 4 };
cout << endl << "Elements of v2 : ";
for (auto i : v2) {
cout << i << " ";
}
}

Output
Elements of v1 : 1.1 2 3.9 4.909
Elements of v2 : 1 2 3 4

Note: The above program will fail compilation in C++14 and below compiler since class
template arguments deduction was added in C++17.
Function Template Arguments Deduction
Function template argument deduction has been part of C++ since the C++98 standard. We can
skip declaring the type of arguments we want to pass to the function template and the compiler
will automatically deduce the type using the arguments we passed in the function call.
Example: In the following example, we demonstrate how functions in C++ automatically
deduce their type by themselves.
C++
// C++ program to illustrate the function template argument
// deduction
#include <iostream>
using namespace std;

// defining function template


template <typename t> t multiply(t first, t second)
{
return first * second;
}

// driver code
int main()
{
auto result = multiply(10, 20);
std::cout << "Multiplication OF 10 and 20: " << result
<< std::endl;

return 0;
}

Output
Multiplication OF 10 and 20: 200

Note: For the function templates which is having the same type for the arguments like
template<typename t> void function(t a1, t a2){}, we cannot pass arguments of different types.

Class Template Arguments Deduction (C++17 Onwards)

The class template argument deduction was added in C++17 and has since been part of the
language. It allows us to create the class template instances without explicitly definition the types
just like function templates.
Example: In the following example, we demonstrate how the compiler automatically class
templates in C++.

// C++ Program to implement


// Class Template Arguments
// Deduction
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;

// defining class template


template <typename t>
class student {
private:
string student_name;
t total_marks;

public:
student();
// parameterized constructor
student(string n, t m)
{
student_name = n;
total_marks = m;
}

void getinfo()
{
cout << "STUDENT NAME: " << student_name << endl;
cout << "TOTAL MARKS: " << total_marks << endl;
cout << "Type ID: " << typeid(total_marks).name()
<< endl;
}
};

int main()
{
// student <int> is used to fulfill
// template requirements
student<int> s1("vipul", 100);
student<int> s2("yash", 100.0);

[Link]();
[Link]();

return 0;
}

Output
STUDENT NAME: vipul
TOTAL MARKS: 100
Type ID: i
STUDENT NAME: yash
TOTAL MARKS: 100
Type ID: d
Here, i means int, and d means double.

You might also like