SCS 202 Object Oriented Program 2024
SCS 202 Object Oriented Program 2024
ON
By
KNIGHT NYARIBO
There are some basic concepts that act as the building blocks of OOPs.
Abstraction
Encapsulation
Inheritance
Polymorphism
Object
An Object can be defined as an entity that has a state and behavior, or in other words, anything
that exists physically in the world is called an object.
It can represent a dog, a person, a table, etc. An object means a combination of data and
programs, which further represent an entity.
1. Encapsulation: Classes allow encapsulating data and related functions into a single unit,
providing data hiding and preventing direct access. Objects represent instances of classes,
enabling modular and organized code structure.
2. Reusability: Classes facilitate code reusability by allowing the creation of multiple objects with
the same structure and behavior. This promotes efficient development and maintenance of
applications.
Classes
Class can be defined as a blueprint of the object. It is basically a collection of objects which act
as building blocks.
A class contains data members (variables) and member functions. These member functions are
used to manipulate the data members inside the class.
Abstraction
Abstraction helps in the data-hiding process. It helps in displaying the essential features without
showing the details or the functionality to the user. It avoids unnecessary information or
irrelevant details and shows only that specific part that the user wants to see.
The benefits of Abstraction includes:
1. Simplified Interface: Abstraction allows hiding complex implementation details and exposing
a simplified interface to the user. This promotes ease of use and reduces complexity, as users
can interact with high-level abstractions without needing to understand the underlying
complexities.
Encapsulation
The wrapping up of data and functions together in a single unit is known as encapsulation.
It can be achieved by making the data members' scope private and the member function’s
scope public to access these data members.
2. Code Organization: Encapsulation helps organize code by grouping related data and functions
together within a class. This improves code readability and maintainability by providing a clear
structure and reducing code clutter.
Inheritance is the process in which two classes have an is-a relationship among each other and
objects of one class acquire properties and features of the other class.
The class which inherits the features is known as the child class, and the class whose features it
inherited is called the parent class. For example, Class Vehicle is the parent class, and Class
Bus, Car, and Bike are child classes.
1. Code Reusability: Inheritance allows classes to inherit properties and behavior from a base
class, promoting code reuse. Derived classes can extend and specialize the functionality of the
base class, eliminating the need to rewrite common code.
As we can see, there are two classes named parent and child. In line 12, the child class inherits
the parent class. Initially, you created an instance of the child class, through which you are
calling name1 and name2 variables; both of these string variables are holding Harley and
Davidson, respectively.
Since child class is inheriting parent class, when you call using the object of the child class, you
get the result name1 as Harley and name2 as Davidson.
Polymorphism
Polymorphism means many forms. It is the ability to take more than one form. It is a feature
that provides a function or an operator with more than one definition. It can be implemented
using function overloading, operator overload, function overriding, and virtual functions. The
benfits include:
2. Code Extensibility: Polymorphism enables the addition of new derived classes that adhere to
the same interface without modifying existing code. This extensibility simplifies code
maintenance and allows for easy integration of new features.
3. Code Readability: Polymorphism enhances code readability by expressing intent and behavior
through the use of abstract interfaces. It allows for more concise and expressive code, as the
focus is on what needs to be done rather than how it is done.
All three classes have a function of the same name, i.e., speed, but the definition of this speed
function is different in all three classes. Inside the main function, firstly, you are invoking the
speed function using the object of the parent class, then using the object of child class Cheetah,
you are again invoking the function, and similarly, you are invoking the function using the
object of dolphin class.
Below is the output of the above program. You can see that when you call the function using
the object of the parent class, it invokes the function of the parent class. But when you call the
function using the object of the child class, it overrides the parent class function and prints the
function of the child class.
Advantages of OOPs
OOPs provide reusability to the code and extend the use of existing classes.
In OOPs, it is easy to maintain code as there are classes and objects, which helps in
making it easy to maintain rather than restructuring.
It also helps in data hiding, keeping the data and information safe from leaking or
getting exposed.
2. Encapsulation
3. Inheritance
4. Polymorphism
#include <iostream>
#include <string>
class Dog {
public:
std::string name;
std::string breed;
void bark() {
};
int main() {
return 0;
}
2. Encapsulation
Encapsulation restricts access to certain components, which can be achieved using private and
public access modifiers.
#include <iostream>
#include <string>
class BankAccount {
private:
std::string owner;
double balance;
public:
balance += amount;
return balance;
};
int main() {
BankAccount account("Alice");
account.deposit(100);
std::cout << "Balance: " << account.getBalance() << std::endl; // Outputs: Balance: 100
return 0;
}
3. Inheritance
Inheritance allows a class to inherit properties and methods from another class.
#include <iostream>
#include <string>
class Animal {
public:
};
public:
};
int main() {
Cat myCat;
return 0;
4. Polymorphism
Polymorphism allows methods to be used interchangeably for different object types, often
achieved using virtual functions.
#include <iostream>
#include <vector>
class Bird {
public:
};
class Dog {
public:
};
animal.speak();
int main() {
Dog myDog;
Bird myBird;
Data Types
All variables use data type during declaration to restrict the type of data to be stored.
Therefore, we can say that data types are used to tell the variables the type of data they can
store.
Whenever a variable is defined in C++, the compiler allocates some memory for that variable
based on the data type with which it is declared. Every data type requires a different amount of
memory.
C++ supports a wide variety of data types and the programmer can select the data type
appropriate to the needs of the application.
Data types specify the size and types of values to be stored. However, storage representation
and machine instructions to manipulate each data type differ from machine to machine,
although C++ instructions are identical on all machines.
These data types are built-in or predefined data types and can be used directly by the
user to declare variables. example: int, char, float, bool, etc. Primitive data types
available in C++ are:
Integer
Character
Boolean
Floating Point
Valueless or Void
Wide Character
2. Derived Data Types: Derived data types that are derived from the primitive or built-in
datatypes are referred to as Derived Data Types. These can be of four types namely:
Function
Array
Pointer
Reference
3. Abstract or User-Defined Data Types: Abstract or User-Defined data types are defined by the
user itself. Like, defining a class in C++ or a structure. C++ provides the following user-defined
datatypes:
Class
Structure
Union
Enumeration
Integer: The keyword used for integer data types is int. Integers typically require 4
bytes of memory space and range from -2147483648 to 2147483647.
Character: Character data type is used for storing characters. The keyword used for the
character data type is char. Characters typically require 1 byte of memory space and
range from -128 to 127 or 0 to 255.
Boolean: Boolean data type is used for storing Boolean or logical values. A Boolean
variable can store either true or false. The keyword used for the Boolean data type
is bool.
Floating Point: Floating Point data type is used for storing single-precision floating-point
values or decimal values. The keyword used for the floating-point data type is float.
Float variables typically require 4 bytes of memory space.
Double Floating Point: Double Floating Point data type is used for storing double-
precision floating-point values or decimal values. The keyword used for the double
floating-point data type is double. Double variables typically require 8 bytes of memory
space.
void: Void means without any value. void data type represents a valueless entity. A void
data type is used for those function which does not return a value.
Wide Character: Wide character data type is also a character data type but this data
type has a size greater than the normal 8-bit data type. Represented by wchar_t. It is
generally 2 or 4 bytes long.
sizeof() operator: sizeof() operator is used to find the number of bytes occupied by a
variable/data type in computer memory.
Example:
int m , x[50];
cout<<sizeof(m); //returns 4 which is the number of bytes occupied by the integer variable
“m”.
cout<<sizeof(x); //returns 200 which is the number of bytes occupied by the integer array
variable “x”.
The size of variables might be different from those shown in the above table, depending on the
compiler and the computer you are using.
#include <iostream>
int main()
return 0;
Output
Size of char : 1
Size of int : 4
Size of long : 8
Size of float : 4
Size of double : 8
Datatype Modifiers
As the name suggests, datatype modifiers are used with built-in data types to modify the length
of data that a particular data type can hold.
Signed
Unsigned
Short
Long
The below table summarizes the modified size and range of built-in datatypes when combined
with the type modifiers:
We can display the size of all the data types by using the sizeof() operator and passing the
keyword of the datatype, as an argument to this function as shown below:
Now to get the range of data types refer to the following chart
Note: syntax<limits.h> header file is defined to find the range of fundamental data-types.
Unsigned modifiers have minimum value is zero. So, no macro constants are defined for the
unsigned minimum value.
Advantages:
Data types provide a way to categorize and organize data in a program, making it easier
to understand and manage.
Each data type has a specific range of values it can hold, allowing for more precise
control over the type of data being stored.
Data types help prevent errors and bugs in a program by enforcing strict rules about
how data can be used and manipulated.
C++ provides a wide range of data types, allowing developers to choose the best type
for a specific task.
Disadvantages:
Using the wrong data type can result in unexpected behavior and errors in a program.
Some data types, such as long doubles or char arrays, can take up a large amount of
memory and impact performance if used excessively.
C++’s complex type system can make it difficult for beginners to learn and use the
language effectively.
The use of data types can add additional complexity and verbosity to a program, making
it harder to read and understand.
IDENTIFIERS
In C++ programming language, identifiers are the unique names assigned to variables,
functions, classes, structs, or other entities within the program. For example, in the below
statement,
num is an identifier.
We can use any word as an identifier as long as it follows the following rules:
1. An identifier can consist of letters (A-Z or a-z), digits (0-9), and underscores (_). Special
characters and spaces are not allowed.
Additionally, C++ is a case-sensitive language so the identifier such as Num and num are
treated as different.
The below images show some valid and invalid C++ identifiers.
In this example, we have used the identifiers by following the guidelines and we use identifiers
to name a class, function, integer data type, etc. If you are not aware
of functions and classes in C++ then don’t you will learn them soon. The below code is run
successfully which means we named them correctly.
#include <iostream>
class Car_24 {
string Brand;
string model;
int year;
};
// function
int _sum = a + b;
cout << "The sum is: " << _sum << endl;
int main()
calculateSum(2, 10);
return 0;
Output
Control structures in C++ are constructs that allow you to control the flow of execution within a
program.
They determine the order in which statements are executed based on certain conditions or
criteria. Control structures enable you to make decisions, iterate over a set of instructions, and
perform different actions based on specific conditions.
Control structures in C++ can be broadly categorized into three types: selection structures,
iteration structures, and jump structures.
Selection Structures
Selection structures in C++ allow you to make decisions based on certain conditions.
They help in choosing a particular path or branch of execution based on the evaluation of an
expression or variable.
1. if statement
if (condition) {
2. if-else statement
The if-else statement extends the functionality of the if statement by allowing you to execute
different code blocks based on the evaluation of a condition.
if (condition) {
} else {
Nested if-else statements are multiple if-else statements nested within each other. They allow
you to perform more complex decision-making by checking multiple conditions.
if (condition1) {
} else {
} else {
Iteration Structures
Iteration structures, also known as loop structures, allow you to repeatedly execute a block of
code as long as a specified condition is true. They are useful when you need to perform
repetitive tasks or iterate over a collection of items.
1. while loop
The while loop executes a block of code repeatedly as long as a specified condition is true.
while (condition) {
// Code to be executed
2. do-while loop
The do-while loop is similar to the while loop but with a crucial difference: it executes the code
block at least once before checking the condition.
do {
// Code to be executed
} while (condition);
3. for loop
The for loop provides a compact and structured way to iterate over a range of values. It
consists of three parts: initialization, condition, and increment/decrement.
// Code to be executed
}
4. range-based for loop
The range-based for loop is a C++11 feature that simplifies iterating over elements of a
container or a range of values.
Jump Structures
Jump structures in C++ allow you to transfer control from one part of the program to another.
They alter the normal sequential flow of execution.
1. break statement
The break statement is used to terminate the execution of a loop or switch statement. It
transfers control to the next statement after the loop or switch.
while (condition) {
if (some_condition) {
// Code to be executed
2. continue statement
The continue statement is used to skip the remaining statements in the current iteration of a
loop and move to the next iteration.
if (i % 2 == 0) {
3. return statement
The return statement is used to terminate the execution of a function and return a value (if the
function has a return type).
int square(int x) {
return x * x;
Error handling structures in C++ are used to handle exceptions and errors that may occur
during program execution. They allow you to gracefully handle exceptional situations and
prevent unexpected program termination.
1. try-catch block
The try-catch block is used to catch and handle exceptions. It consists of a try block where you
place the code that might throw an exception, and one or more catch blocks that handle
specific types of exceptions.
try {
} catch (...) {
In the above code, the try block contains the code that could potentially throw an exception. If
an exception is thrown, the catch blocks are evaluated sequentially to find a matching exception
type. The first matching catch block is executed, and the program flow continues from there.
ARRAYS OVERVIEW
Arrays in C++ are a collection of similar data type elements. They are one of the most versatile
and powerful data structures in C++.
An array in C++ programming language is a powerful data structure that allows users to store
and manipulate a collection of elements, all of the same data typein a single variable. Simply, it
is a collection of elements of the same data type.
Arrays are the derived data type in C++ that can store values of both - fundamental data
types like int, and char; and derived data types like pointers, and structure. The values get
stored at contagious memory locations that can be accessed with their index number.
Syntax
dataType arrayName[arraySize];
Example
int a[5];
Here, an integer type array a is declared with the size 5. It can store 5 integer values.
2. Multi-dimensional array: It is an array that contains one or more arrays as its elements.
Though we haven't specified the size, the compiler understands the size as 5 due to the
initialization of 5 elements.
int marks[5];
marks[1]=60;
marks[2]=70;
marks[3]=85;
marks[4]=75;
What if the elements initialized are less than the size of the array declared?
Example
Here an array a of size 5 is declared. We have initialized it with 3 elements only. In this case,
the compiler assigns random values to the remaining places. Many a time, this random value
is 0.
To access the array elements, use the index number of the required element. The array index
starts with 0. The index of the last element is n-1.
Example in C++
#include <iostream>
int main() {
return 0;
Output
25
50
75
100
Remember that when you access an unavailable element in an array, the program may result in
an unexpected output (undefined behavior). Sometimes you might get an error and some other
times your program may run correctly.
Example
#include <iostream>
int main()
a[3] = 60;
return 0;
Output
60
Example
#include <iostream>
#include <string>
int main() {
}
return 0;
In the above code, we have created a string array, fruits. We are printing all the fruit names
along with its index inside the fruits array using for loop.
Output
Apple
Mango
Banana
Orange
Grapes
We have seen the for-each loop in the loops in C++ programming section. This loop is
used exclusively to traverse through elements in an array. In this loop, we don't need to
specify the number of iterations given by the size of the array.
Example
#include <iostream>
int main() {
return 0;
Output
Apple
Mango
Banana
Orange
Grapes
If we haven't specified the size of the array during declaration, we can use
the sizeof() operator to traverse through the array
Example in C++
#include <iostream>
#include <string>
int main() {
return 0;
Output
Apple
Mango
Banana
Orange
Grapes
We can use the cin function to take inputs of an array from the user.
Example in C++
// Program to take values of the array from the user and print the array
#include <iostream>
int a[5];
return 0;
The above code uses the for loop to take input values for an array a. After storing the elements
in an array, it again uses the for loop to print all of them.
Output
Displaying integers:
1
2
In this type of array, two indexes are there to describe each element, the first index represents
a row, and the second index represents a column.
Syntax of a 2D Array
data_Type array_name[m][n];
Here,
m: row number
n: column number
#include <iostream>
int main()
int arr[6][6];
// Initialization
arr[i][j] = i + j;
}
return 0;
Output
012345
123456
234567
345678
456789
5 6 7 8 9 10
The 3D array uses three dimensions. There are three indices—the row index, column index, and
depth index to uniquely identify each element in a 3D array.
Syntax of a 3D Array
data_Type array_name[d][r][c];
Here,
#include <iostream>
int main()
int arr[3][3][3];
arr[i][j][k] = i + j + k;
return 0;
Output
1st layer:
345
456
567
2st layer:
456
567
678
3st layer:
567
678
789
Efficient memory usage: Arrays in C++ use contiguous memory locations to store the
elements, thus making it efficient to allocate and access data.
Easy access to elements: Elements in an array can be accessed using their index,
making it easy to retrieve specific data from the array.
Better performance: Accessing elements in an array using an index is faster than using
other data structures like linked lists or trees. This is because the index provides direct
access to the memory location where the element is stored.
Compatible with other data structures: Arrays can be used in conjunction with other
data structures in C++, such as stacks and queues, to implement complex data
structures and algorithms.
Fixed-size: Arrays in C++ have a fixed size determined at the time of declaration. There
is no dynamic increase in the size of an array.
Memory allocation: Arrays in C++ are allocated in contiguous memory blocks. If the
array is very large, there may not be enough contiguous memory available for
allocation.
No bounds checking: C++ does not perform any bounds checking on arrays, so it is
possible to access memory outside of the bounds of the array. This can lead to
segmentation faults or other memory-related errors.
Limited flexibility: Arrays in C++ have limited flexibility due to fixed size and dimensions.
This makes it difficult to implement certain algorithms and data structures that require
dynamic resizing and manipulation.
Inefficient for insertion and deletion: Inserting or deleting elements from an array in
C++ can be inefficient, as it requires shifting all the elements after the insertion or
deletion point to make room or fill in the gap. This can be time-consuming, especially for
large arrays.
FUNCTIONS
A function is defined as a group of statements or a block of code that carries out specific tasks.
You need to give a particular name to the function and write some logic or group of information
inside it.
And then you can invoke that function from the main function. For example, you can name a
function as factorial, and inside that function, you can write the logic to find the factorial of a
number. And then, you can use it whenever you need that function in the program.
Functions are used to minimize the repetition of code, as a function allows you to write the
code inside the block.
You can call that block whenever you need that code segment, rather than writing the code
repeatedly. It also helps in dividing the program into well-organized segments.
Function Syntax
Here, the return type is the data type of the value that the function will return. Then there is
the function name, followed by the parameters which are not mandatory, which means a
function may or may not contain parameters.
Example:
Declaration:
A function can be declared by writing its return type, the name of the function, and the
arguments inside brackets. It informs the compiler that this particular function is present.
In C++, if you want to define the function after the main function, then you have to declare
that function first.
Definition:
A function definition specifies the body of the function. The declaration and definition of a
function can be made together, but it should be done before calling it.
Calling:
When you define a function, you tell the function what to do and to use that function; you have
to call or invoke the function.
When a function is called from the main function, then the control of the function is transferred
to the function that is called. And then that function performs its task. When the task is
finished, it returns the control to the main function.
Built-in functions
User-defined functions
Built-in Functions:
These are functions that are already present in C++; their definitions are already provided in
the header files. The compiler picks the definition from header files and uses them in the
program.
User-defined Functions:
These are functions that a user creates by themselves, wherein the user gives their own
definition.
No argument and no return value: In this type, as the name suggests, it passes no arguments
to the function, and you print the output within the function. So, there is no return value.
No argument but return value: In this type, it passes no arguments to the function, but there is
a return value.
Argument but no return value: In this type of function, it passes arguments, but there is no
return value. And it prints the output within the function.
Argument and return value: In this type of function, it passes arguments, and there is also a
return value.
You can invoke or call a function in two ways: call by value and call by function.
Call By Value:
In this calling method, you only pass the copies of the variable and not the actual argument to
the function.
As the copies of the variable or arguments are being passed, any changes made to the variable
in the function don’t affect the actual argument.
For example:
In the above program, you pass the variables to the function through the call by value method,
i.e., you pass the copies of variables. So it won’t reflect the change inside the main function
where the actual variables are present. But if you print the output in the called function, then
you can see the changes over there.
Call By Reference:
In this calling technique, you pass the address or reference of the argument, and the function
receives the memory address of the argument. In this case, the actual value of the variable
changes, or you can say that it reflects the changes back to the actual variable.
In this example, you pass the reference of the variable using & (ampersand) sign and not the
copy of the variable, so the actual value also changes in this case.
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 ‘typename’. The second
keyword can always be replaced by the keyword ‘class’.
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().
Example:
C++
// 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()
return 0;
Output
C++
// Driver Code
int main()
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++
private:
T* ptr;
int size;
public:
void print();
};
ptr[i] = arr[i];
int main()
int arr[5] = { 1, 2, 3, 4, 5 };
a.print();
return 0;
Output
12345
Yes, like normal parameters, we can pass more than one data type as arguments to templates.
The following example demonstrates the same.
Example:
C++
T x;
U y;
public:
};
int main()
A<char, char> a;
A<int, double> b;
return 0;
Output
Constructor Called
Constructor Called
Yes, like normal parameters, we can specify default arguments to templates. The following
example demonstrates the same.
Example:
C++
public:
T x;
U y;
};
int main()
return 0;
Output
Constructor Called
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.
Each instance of a template contains its own static variable. See Templates and Static
variables for more details.
Template specialization allows us to have different codes for a particular data type.
See Template Specialization for more details.
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 256 with a variable, we get a compiler error.
Example:
C++
int m = max;
if (arr[i] < m)
m = arr[i];
return m;
int main()
char arr2[] = { 1, 2, 3 };
return 0;
Output
10
Here is an example of a C++ program to show different data types using a constructor and
template. We will perform a few actions
Example:
C++
public:
// end of info()
}; // end of class
// Main Function
int main()
// clrscr();
return 0;
Output
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:
In general, when we want to use the multiply() function for integers, we have to call it like this:
multiply(23, 5);
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 that the template argument deduction for classes is only available
since C++17, so if we try to use the auto template argument deduction for a class in previous
version, it will throw an error.
Example of Template Argument Deduction
The below example demonstrates how the STL vector class template deduces the data type
without being explicitly specified.
C++
#include <vector>
int main()
Output
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.
C++
// driver code
int main()
<< std::endl;
return 0;
Output
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++
#include <iostream>
#include <string>
#include <typeinfo>
private:
string student_name;
T total_marks;
public:
// Parameterized constructor
student(string n, T m)
: student_name(n)
, total_marks(m)
}
void getinfo()
<< endl;
};
int main()
s1.getinfo();
s2.getinfo();
return 0;
Output
This feature is enabled in the C++ 14 version of the C++ programming language.
It has made creating constants and then using them for different datatypes easy for
programmers.
Variable templates help the developers in defining parameterized constants with ease and
simplicity to understand the types and values of constants used in the code.
It provides flexibility while dealing with mathematical constants, configuration values, or other
compile-time constants that depend on the type or dimensions.
where,
Let’s take a look at a simple example of a variable template that defines the constant e (euler):
In this code, euler (e) is a variable template that can be instantiated with different types. We’ll
see how to use it in the below code.
#include <iostream>
return 0;
Output
Integer Type of e: 2
The variable templates in classes is used to declare static data members template.Also, for
static data member templates, you may need to provide definitions outside the class definition.
Example
// template
#include <iostream>
class limits {
public:
};
// definition
template <typename T> const T limits::min = T(10.24);
int main()
return 0;
Output
10
10.24
In this example, we first declare a static data member template min within the limits class.
Then, we provide a definition for min outside the class.
Just like class and function templates, the types of variable templates can also be implicitly
deduced by the compiler in the case where there is no type provided in the template
instantanization.
In this example. we will take a constant pi and will not specify the type of the constant.
#include <iostream>
return pi<T> * r * r;
int main()
return 0;
Output
2. It provides a way to write the generic code that will work for different data types.
POINTERS
Pointers in C++ point to the memory location of another variable. They let us access any
location in the computer's memory, acting as variables.
Pointers are variables that contain the memory address of another variable instead of a direct
value. Such variables can be of type. int, float, char, etc. By referencing this memory address,
programmers can access and modify data indirectly.
Dynamic memory allocation - In the C++ programming language, the programmers can
dynamically allocate memory by using the malloc() and calloc() functions, mainly where
the pointer is used. This is the primary use of pointers in C++.
We do not initialize the pointer; we declare it using the * (asterisk symbol) before a pointer's
name or after the data type. This asterisk sign acts as the ticket to enter the address of the
variables. If a pointer has an asterisk with it, it will show the value of the variable.
Syntax
datatype *var_name;
Example
The procedure of initializing a pointer is where we give the memory address of another variable
using the & (address of) operator.
Example
#include <iostream>
int main() {
// declare pointer variable 'ptr' and initialize it with the address of 'x'
// print value of x
// print address of x
<< endl;
cout << "Content of the address pointed to by ptr (*ptr) = " << *ptr << endl;
return 0;
x = 42
ptr = 0x7ffeb5f7b3c4
* used in the above example can confuse you. It serves two purposes:
Example
#include <iostream>
int main() {
// declare pointer variable 'ptr' and initialize it with the address of 'x'
// print value of x
// print *ptr
<< endl;
x = 70;
// print x
// print *ptr
<< endl;
*ptr = 60;
// print x
// print *ptr
return 0;
In the above C++ code in C++ Compiler, ptr points to the address of x. Therefore
Output
x = 42
*ptr = 42
Changing value of x to 70:
x = 70
*ptr = 70
x = 60
*ptr = 60
1. NULL Pointer
A NULL pointer indicates that it has not been initialized and points to nowhere in memory.
Syntax
#include <iostream>
int main() {
if (ptr == nullptr) {
cout << "This pointer is called the null pointer." << endl;
return 0;
Output
2. Integer Pointers
The memory location of an integer variable is stored in integer pointers.
Syntax
int* intPointer;
#include <iostream>
int main() {
// Declare an integer pointer and initialize it with the address of the variable
int *ptr = #
*ptr = 100;
std::cout << "Modified value of num: " << num << std::endl;
return 0;
Output
Value of num: 42
The initial element of an array may be referenced by array pointers. It is applicable for random
access of the array elements by using the pointer instead of the array indices. A pointer not
only stores the memory address of the first element of an array but is also associated with the
element type of the array. This means that the pointer "knows" the type of data it points to,
enabling it to access and manipulate the array elements correctly.
Syntax
int arr[5];
#include <iostream>
int main() {
std::cout << *(p + i) << " "; // Accessing array elements through pointer arithmetic
return 0;
Output
10 20 30 40 50
4. Function Pointers
You can call functions indirectly by using function pointers that save the address of a function.
Syntax
#include <iostream>
return a + b;
return a - b;
int main() {
// Initialize the function pointer with the address of the add function
operation = add;
operation = subtract;
return 0;
Output
Result of addition: 15
Result of subtraction: 5
5. void Pointer
Void pointers can point to any data and can be type casted to any type. It doesn’t have an
associated data type. It can hold the address of a data type of integer, a float, or a string.
Syntax
void* voidPointer;
#include <iostream>
int main() {
int x = 105;
float y = 89;
void *p = nullptr;
p = &x;
p = &y;
return 0;
}
Output
Float value: 89
6. Structure Pointer
A structure pointer points to the address of a structure. Pointers to structures help in dynamic
memory allocation, passing function parameters to big structures with less overhead and data
structures, such as linked lists and trees.
Syntax
struct MyStruct {
int data;
};
#include <iostream>
#include <cstring>
struct Employee {
int id;
char name[20];
};
int main() {
Employee *ptr = new Employee; // Dynamically allocate memory for one Employee struct
ptr->id = 789;
strcpy(ptr->name, "Sourav Kumar");
delete ptr;
return 0;
Output
7. Double Pointers
Double pointers are pointers to pointers, i.e., they point to the memory address of another
pointer and are frequently employed in linked lists or multi-dimensional arrays.
Syntax
#include <iostream>
int main() {
std::cout << "Single pointer points to value: " << *singlePtr << std::endl;
std::cout << "Double pointer points to single pointer: " << **doublePtr << std::endl;
return 0;
Output
Value: 50
Pointers help to reduce the code and improve the performance of the program. It mainly
assists in retrieving trees, strings, and many more. Pointers are primarily used
with arrays, functions, and structures.
The programmer or user can return multiple values from a particular function with the
help of the pointer
Pointers help users access any memory location in the computer's memory.
FILE ORGANIZATION
File handling is used to store data permanently in a computer. Using file handling we can store
our data in secondary memory (Hard disk).
How to achieve the File Handling
Streams in C++ :-
We give input to the executing program and the execution program gives back the output.
The sequence of bytes given as input to the executing program and the sequence of bytes that
comes as output from the executing program are called stream.
In other words, streams are nothing but the flow of data in a sequence.
The input and output operation between the executing program and the devices like keyboard
and monitor are known as “console I/O operation”.
The input and output operation between the executing program and files are known as “disk
I/O operation”.
The I/O system of C++ contains a set of classes which define the file handling methods.
These classes are derived from fstream and from the corresponding iostream class. These
classes, designed to manage the disk files, are declared in fstream and therefore we must
include this file in any program that uses files.
1. ios:-
This class is the base class for other classes in this class hierarchy.
This class contains the necessary facilities that are used by all the other derived classes
for input and output operations.
2. istream:-
The extraction operator(>>) is overloaded in this class to handle input streams from
files to the program execution.
This class declares input functions such as get(), getline() and read().
3. ostream:-
The insertion operator(<<) is overloaded in this class to handle output streams to files
from the program execution.
4. streambuf:-
This class contains a pointer which points to the buffer which is used to manage the
input and output streams.
5. fstreambase:-
This class provides operations common to the file streams. Serves as a base for fstream,
ifstream and ofstream class.
6. ifstream:-
Inherits the functions get(), getline(), read(), seekg() and tellg() functions from the
istream.
7. ofstream:-
8. fstream:-
This class provides support for simultaneous input and output operations.
Inherits all the functions from istream and ostream classes through iostream.
9. filebuf:-
We can also use file buffer member function to determine the length of the file.
In C++, files are mainly dealt by using three classes fstream, ifstream, ofstream available in
fstream headerfile.
Now the first step to open the particular file for read or write operation. We can open file by
1. passing file name in constructor at the time of object creation
2. using the open method
For e.g.
Modes :
Member
Constant Stands For Access
ios::binary binary Operations are performed in binary mode rather than text.
ios::ate at end The output position starts at the end of the file.
Do not
ios::nocreate Does not allow to create new file if it does not exist.
create
Do not
ios::noreplace Does not replace old file with new file.
replace
Both ios::app and ios::ate take us to the end of the file when it is opened. The difference
between the two modes is that ios :: app allow us to add data to the end of the file only, while
ios :: ate mode permits us add data or to modify the existing data anywhere in the file.
Default Open Modes :
Ifstream ios::in
ofstream ios::out
Input :
Welcome in Kenya. Best way to learn things.
-1
Output :
Welcome in Kenya. Best way to learn things.
C++
/* File Handling with C++ using ifstream & ofstream class object*/
/* To write the Content in File*/
/* Then to read the content of file*/
#include <iostream>
// Driver Code
int main()
string line;
// Press -1 to exit
if (line == "-1")
break;
return 0;
C++
string line;
// Press -1 to exit
if (line == "-1")
break;
}
// Execute a loop until EOF (End of File)
// point read pointer at beginning of file
fio.seekg(0, ios::beg);
while (fio) {
return 0;
C++
#include <iostream>
#include <string>
// Use the standard namespace
using namespace std;
int main()
<< endl;
Output
#include<iostream>
#include<fstream>
main()
{
int rno,fee;
char name[50];
ifstream fin("d:/student.doc");
fin.close();
cout<<endl<<rno<<"\t"<<name<<"\t"<<fee;
return 0;
}
INTRODUCTION TO CONSTRUCTOR AND DESTRUCTOR
While programming, sometimes there might be the need to initialize data members and
member functions of the objects before performing any operations. Data members are the
variables declared in any class by using fundamental data types (like int, char, float, etc.) or
derived data types (like class, structure, pointer, etc.). The functions defined inside the class
definition are known as member functions.
Suppose you are developing a game. In that game, each time a new player registers, we need
to assign their initial location, health, acceleration, and certain other quantities to some default
value.
This can be done by defining separate functions for each quantity and assigning the quantities
to the required default values. For this, we need to call a list of functions every time a new
player registers. Now, this process can become lengthy and complicated.
What if we can assign the quantities along with the declaration of the new player automatically?
A constructor can help do this in a better and simpler way.
Moreover, when the player deletes his account, we need to deallocate the memory assigned to
him. This can be done using a destructor.
A Constructor is a special member function of a class and shares the same name as of class,
which means the constructor and class have the same name.
Constructor is called by the compiler whenever the object of the class is created, it allocates the
memory to the object and initializes class data members by default values or values passed by
the user while creating an object.
Constructors don’t have any return type because their work is to just create and initialize an
object.
Syntax of Constructor:
class scaler {
public:
// Constructor
scaler() {
// Constructor body.
}
};
A constructor can be made public, private, or protected per our program's design.
Constructors are mostly made public, as public methods are accessible from everywhere,
thus allowing us to create the object of the class anywhere in the code. When a
constructor is made private, other classes cannot create instances of the class. This is
used when there is no need for object creation. Such a case arises when the class only
contains static member functions(i.e., the functions that are independent of any class
object and can be accessed using a class name with scope resolution operator, i.e. ::).
A constructor in C++ cannot be inherited. However, a derived class can call the base
class constructor. A derived class(i.e., child class) contains all members and member
functions(including constructors) of the base class.
Constructor functions are not inherited, and their addresses cannot be referenced.
The constructor in C++ cannot be virtual. A virtual table(also called vtable) is made for
each class having one or more virtual functions. Virtual functions ensure that the correct
function is called for an object regardless of the type of reference used for the function
call. Whenever an object is created of such a class, it contains a ‘virtual-pointer’ that
points to the base of the corresponding vtable. Whenever there is a virtual function call,
the vtable refers to the function address.
But when a class constructor is executed, there is no virtual table created yet in the memory,
meaning no virtual pointer is defined yet. As a result, a constructor cannot be declared virtual.
1. Default Constructors
2. Parameterized Constructors
3. Copy Constructors
4. Dynamic Constructors
1. Default Constructor:
A constructor which does not receive any parameters is called a Default Constructor or a Zero
Argument Constructor. Every class object is initialized with the same set of values in the default
constructor.
Even if a constructor is not defined explicitly, the compiler will provide a default constructor
implicitly.
Syntax:
Example:
#include <bits/stdc++.h>
class Employee {
public:
int age;
// Default constructor.
Employee() {
};
int main() {
return 0;
Output:
50
Note: Default constructor provided by the compiler will be called, which will initialize the object
data members to the default value, which will be 0 or any random integer value in the example
provided below.
Example:
Considering the previous example, the default constructor (i.e., Employee() in Employee class
definition) defined by the programmer assigns the data member age to a value of 50.
But in the given example here, as the data member age is not assigned to any value, the
compiler calls the default constructor, and age is initialized to 0 or unpredictable garbage
values.
#include <bits/stdc++.h>
class Employee {
public:
int age;
int main() {
// Object e1 declared.
Employee e1;
return 0;
Output:
2. Parameterized Constructor
Using the default constructor, it is impossible to initialize different objects with different initial
values. What if we need to pass arguments to constructors which are needed to initialize an
object? There is a different type of constructor called Parameterized Constructor to solve this
issue.
A Parameterized Constructor is a constructor that can accept one or more arguments. This
helps programmers assign varied initial values to an object at the creation time.
Example:
#include <iostream>
class Employee {
public:
int age;
// Parameterized constructor
Employee(int x) {
};
int main() {
Employee c2(30);
Employee c3(50);
return 0;
}
Output:
40
30
50
2. Copy Constructor
A Copy constructor in C++ is a type of constructor used to create a copy of an already existing
object of a class type. The compiler provides a default Copy Constructor to all the classes. A
copy constructor comes into the picture whenever there is a need for an object with the same
values for data members as an already existing object. A copy constructor is invoked when an
existing object is passed as a parameter.
Syntax:
//Copy constructor
Employee :: Employee(Employee &ptr)
Example:
#include<iostream>
class Employee {
private:
// Data members
int salary, experience;
public:
// Parameterized constructor
Employee(int x1, int y1) {
salary = x1;
experience = y1;
}
// Copy constructor
Employee(const Employee &new_employee) {
salary = new_employee.salary;
experience = new_employee.experience;
void display() {
};
// main function
int main() {
// Parameterized constructor
Employee employee1(34000, 2);
// Copy constructor
Employee employee2 = employee1;
employee1.display();
employee2.display();
return 0;
Output:
Salary: 34000
Years of experience: 2
Years of experience: 2
Explanation:
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 34000 and 2, respectively, with the help of a parameterized 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 and
experience of object employee2 are assigned to values possessed by the salary, and experience
data members of object employee1 (i.e., 34000, 2), respectively.
4. Dynamic Constructor
When the allocation of memory is done dynamically (i.e., Memory is allocated to variables at
run-time of the program rather than at compile-time) using a dynamic memory allocator new in
a constructor, it is known as a Dynamic constructor. By using this, we can dynamically initialize
the objects.
#include <iostream>
class Employee {
int* due_projects;
public:
// Default constructor.
Employee() {
*due_projects = 0;
// Parameterized constructor.
Employee(int x) {
void display() {
};
// Main function
int main() {
employee1.display();
employee2.display();
return 0;
Output:
10
Explanation:
Here, integer type pointer variable is declared in class which is assigned memory dynamically
when the constructor is called. When we create object employee1 of class Employee in the first
line of the main() function, the default constructor(i.e. Employee() in class Employee definition)
is called automatically, and memory is assigned dynamically to the pointer type
variable(i.e., *due_projects) and initialized with value 0.
And similarly, when employee2 is created in the third line of the main() function, the
parameterized constructor(i.e., Employee(int x) in the class definition) is called, and memory is
assigned dynamically.
Syntax of Destructor:
class scaler {
public:
//constructor
scaler();
//destructor
~scaler();
};
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.
Implementation of Constructors and Destructors in C++
#include <iostream>
class Department {
public:
Department() {
// Constructor is defined.
cout << "Constructor Invoked for Department class" << endl;
~Department() {
// Destructor is defined.
cout << "Destructor Invoked for Department class" << endl;
};
class Employee {
public:
Employee() {
// Constructor is defined.
cout << "Constructor Invoked for Employee class" << endl;
~Employee() {
// Destructor is defined.
cout << "Destructor Invoked for Employee class" << endl;
}
};
int main(void) {
return 0;
Output:
Explanation:
When an object named d1 is created in the first line of main(), i.e. (Department d1), its
constructor is automatically invoked during the creation of the object. As a result, the first line
of output, “Constructor Invoked for Department class,” is printed. Similarly, when the e2 object
of the Employee class is created in the second line of main(), i.e. (Employee e2), the
constructor corresponding to e2 is invoked automatically by the compiler, and “Constructor
Invoked for Employee class” is printed.
A destructor is always called in reverse order as that of a constructor. When the scope of the
main function ends, the destructor corresponding to object e2 is invoked first. This leads to
printing “Destructor Invoked for Employee class”. Lastly, the destructor corresponding to object
d1 is called, and “Destructor Invoked for Department class” is printed.
S.
Constructors Destructors
No.
Constructor is invoked to initialize the object of a class Destructor is invoked when the
1
by the compiler. instance is destroyed.
Declared as Class_Name(arguments if
2 Declared as ~Class_Name(){}.
any){//constructor body}.
S.
Constructors Destructors
No.
The C++ interfaces are implemented using abstract classes and these abstract classes should
not be confused with data abstraction which is a concept of keeping implementation details
separate from associated data.
A class is made abstract by declaring at least one of its functions as pure virtual function.
A pure virtual function is specified by placing "= 0" in its declaration as follows −
class Box {
public:
private:
};
The purpose of an abstract class (often referred to as an ABC) is to provide an appropriate base
class from which other classes can inherit. Abstract classes cannot be used to instantiate
objects and serves only as an interface. Attempting to instantiate an object of an abstract class
causes a compilation error.
Thus, if a subclass of an ABC needs to be instantiated, it has to implement each of the virtual
functions, which means that it supports the interface declared by the ABC. Failure to override a
pure virtual function in a derived class, then attempting to instantiate objects of that class, is a
compilation error.
Classes that can be used to instantiate objects are called concrete classes.
Consider the following example where parent class provides an interface to the base class to
implement a function called getArea() –
#include <iostream>
// Base class
class Shape {
public:
void setWidth(int w) {
width = w;
void setHeight(int h) {
height = h;
protected:
int width;
int height;
};
// Derived classes
public:
int getArea() {
};
int getArea() {
};
int main(void) {
Rectangle Rect;
Triangle Tri;
Rect.setWidth(5);
Rect.setHeight(7);
cout << "Total Rectangle area: " << Rect.getArea() << endl;
Tri.setWidth(5);
Tri.setHeight(7);
cout << "Total Triangle area: " << Tri.getArea() << endl;
return 0;
When the above code is compiled and executed, it produces the following result −
You can see how an abstract class defined an interface in terms of getArea() and two other
classes implemented same function but with different algorithm to calculate the area specific to
the shape.
Designing Strategy
An object-oriented system might use an abstract base class to provide a common and
standardized interface appropriate for all the external applications. Then, through inheritance
from that abstract base class, derived classes are formed that operate similarly.
The capabilities (i.e., the public functions) offered by the external applications are provided as
pure virtual functions in the abstract base class. The implementations of these pure virtual
functions are provided in the derived classes that correspond to the specific types of the
application.
This architecture also allows new applications to be added to a system easily, even after the
system has been defined.
EXCEPTION HANDLING
An exception is a problem that arises during the execution of a program. A C++ exception is a
response to an exceptional circumstance that arises while a program is running, such as an
attempt to divide by zero.
Exceptions provide a way to transfer control from one part of a program to another. C++
exception handling is built upon three keywords: try, catch, and throw.
throw − A program throws an exception when a problem shows up. This is done using
a throw keyword.
try − A try block identifies a block of code for which particular exceptions will be
activated. It's followed by one or more catch blocks.
Assuming a block will raise an exception, a method catches an exception using a combination of
the try and catch keywords. A try/catch block is placed around the code that might generate an
exception. Code within a try/catch block is referred to as protected code, and the syntax for
using try/catch as follows −
try {
// protected code
} catch( ExceptionName e1 ) {
// catch block
} catch( ExceptionName e2 ) {
// catch block
} catch( ExceptionName eN ) {
// catch block
You can list down multiple catch statements to catch different type of exceptions in case
your try block raises more than one exception in different situations.
Throwing Exceptions
Exceptions can be thrown anywhere within a code block using throw statement. The operand of
the throw statement determines a type for the exception and can be any expression and the
type of the result of the expression determines the type of exception thrown.
Example
if( b == 0 ) {
return (a/b);
Catching Exceptions
The catch block following the try block catches any exception. You can specify what type of
exception you want to catch and this is determined by the exception declaration that appears in
parentheses following the keyword catch.
try {
// protected code
} catch( ExceptionName e ) {
Above code will catch an exception of ExceptionName type. If you want to specify that a catch
block should handle any type of exception that is thrown in a try block, you must put an ellipsis,
..., between the parentheses enclosing the exception declaration as follows −
try {
// protected code
} catch(...) {
Example
The following is an example, which throws a division by zero exception and we catch it in catch
block.
#include <iostream>
if( b == 0 ) {
return (a/b);
int main () {
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
return 0;
Because we are raising an exception of type const char*, so while catching this exception, we
have to use const char* in catch block. If we compile and run above code, this would produce
the following result −
C++ provides a list of standard exceptions defined in <exception> which we can use in our
programs. These are arranged in a parent-child class hierarchy shown below −
Here is the small description of each exception mentioned in the above hierarchy −
std::exception
1
An exception and parent class of all the standard C++ exceptions.
std::bad_alloc
2
This can be thrown by new.
std::bad_cast
3
This can be thrown by dynamic_cast.
4 std::bad_exception
This is useful device to handle unexpected exceptions in a C++ program.
std::bad_typeid
5
This can be thrown by typeid.
std::logic_error
6
An exception that theoretically can be detected by reading the code.
std::domain_error
7
This is an exception thrown when a mathematically invalid domain is used.
std::invalid_argument
8
This is thrown due to invalid arguments.
std::length_error
9
This is thrown when a too big std::string is created.
std::out_of_range
10 This can be thrown by the 'at' method, for example a std::vector and
std::bitset<>::operator[]().
std::runtime_error
11
An exception that theoretically cannot be detected by reading the code.
std::overflow_error
12
This is thrown if a mathematical overflow occurs.
std::range_error
13
This is occurred when you try to store a value which is out of range.
std::underflow_error
14
This is thrown if a mathematical underflow occurs.
Define New Exceptions
You can define your own exceptions by inheriting and overriding exception class functionality.
Example
Following is the example, which shows how you can use std::exception class to implement your
own exception in standard way −
Open Compiler
#include <iostream>
#include <exception>
};
int main() {
try {
throw MyException();
} catch(MyException& e) {
} catch(std::exception& e) {
//Other errors
MyException caught
C++ Exception
THREADS AND CONCURRENCY
Here, what() is a public method provided by exception class and it has been overridden by all
the child exception classes. This returns the cause of an exception.
Concurrency refers to the ability to process multiple tasks or threads at the same time. It is
used to improve the program’s performance and response time. In this article, we will discuss
how concurrency is achieved in C++ and what are its benefits.
Concurrency in C++
In C++, the support for concurrency was first added in C++ 11 to improve the performance of
the program and enable multitasking. The components such as thread, mutex, memory model,
and various synchronization primitives were added as the part of Concurrency Support Library.
Although concurrency provides multitasking, it doesn’t mean that the tasks are executed
simultaneously in different processing units. Instead, it works by task switching i.e. doing some
task for a small time, then moving to the other tasks, and then coming back again to the first
task. It will keep doing it till both of the tasks are done.
Threads in C++
Threads are the basic unit of multitasking. The concurrent execution of the tasks is done by
creating multiple threads in a multithreaded environment. The C++ provides a <thread> library
for creating and managing threads.
1. Deadlocks
Deadlock refers to the situation where the two or more threads are blocked the forever waiting
for the each other. The careful synchronization is essential to the prevent deadlocks.
2. Race Conditions
Race conditions happens when two or more the threads access shared data concurrently
leading to the undefined behaviour.
3. Starvation
Starvation is the condition where a thread is unable to the gain regular access to the shared
resources.
The above problems can be avoided by proper synchronization between the threads.
Thread synchronization can be done using the following components provided in the C++:
1. Mutex and Locks
The Mutual Exclusion and Locks are used to the protect shared resources. Ensures that only
one thread accesses critical sections at a time. C++ have <mutex> header file which contains
the std::mutex classes.
2. Condition Variables
Condition Variables are used for thread synchronization by acting as a flag that notifies the
threads when the shared resources are free. It provides a wait-free synchronization in contrast
to what mutex and locks do. C++ have <condition_variable> header that contains the
condition_variable object.
The <future> and <promise> are used for the asynchronous task execution. This method is
only viable when the thread tasks are independent of each other.
4. Semaphores
It is also a synchronization primitive that counts the number of threads accessing the shared
resource. If this count exceeds the number of access available, the semaphore will block the
access till the count is freed.
C++
#include <mutex>
#include <thread>
#include <vector>
// performing operation
for (int i = start; i <= end; i++) {
sum += v[i];
// driver code
int main()
t2.join();
for (auto i : v) {
// printing sum
cout << "Sum: " << sum;
return 0;
Output
Concurrency vs Parallelism
The terms concurrency and parallelism are often told as same but there is some difference
between them. The below table lists the major differences between the concurrency and
parallelism:
Characteristics Concurrency Parallelism
Benefits of Concurrency
Improved Performance: The utilizing multiple CPU cores and executing different parts of
your program can improve the performance drastically.
Responsiveness: The Applications remain responsive and don’t freeze while performing
intensive operations.
Resource Utilization: The Efficiently utilize system resources and make the most of the
modern multi-core processors.