0% found this document useful (0 votes)
18 views

SCS 202 Object Oriented Program 2024

Uploaded by

chembri022
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

SCS 202 Object Oriented Program 2024

Uploaded by

chembri022
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 114

LECTURE NOTES

ON

OBJECT ORIENTED PROGRAMMING

Course Code: SCS-202

By

KNIGHT NYARIBO

COMPUTER SCIENCE DEPARTMENT


Basic Object-Oriented Programming (OOPS) Concept

There are some basic concepts that act as the building blocks of OOPs.

 Classes & Objects

 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.

The benefits of classes and objects include:

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.

3. Modularity: Classes provide a modular approach to programming by grouping related data


and functions together. This enhances code organization, readability, and understandability.

 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.

2. Code Maintenance: By focusing on essential features and hiding unnecessary implementation


details, abstraction improves code maintainability. Changes made to the underlying
implementation are isolated, reducing the impact on other parts of the code base.

3. Flexibility: Abstraction enables the creation of generalized interfaces, which can be


implemented differently for various use cases. This provides flexibility and allows developers to
adapt and extend the functionality of the code without affecting the code using abstraction.

 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.

Encapsulation makes the data non-accessible to the outside world.

The benefits of encapsulation include:

1. Data Protection: Encapsulation hides the internal implementation details of an object,


protecting the data from unauthorized access or modification. It provides data integrity and
maintains the consistency of the object's state.

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.

3. Code Reusability: Encapsulation facilitates code reusability by encapsulating functionality


within objects. Objects can be easily reused in different parts of the code or in different
projects, promoting efficient development and reducing redundant code.
 Inheritance

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.

The benefits of Inheritance include:

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.

2. Polymorphism: Inheritance enables polymorphism, where objects of derived classes can be


treated as objects of their base class. This allows for more flexible and dynamic programming,
as different derived classes can be used interchangeably through a common interface.

3. Hierarchical Organization: Inheritance establishes a hierarchical relationship among classes,


reflecting real-world or conceptual hierarchies. This improves code organization,
understandability, and maintainability by representing relationships and dependencies in a
structured manner.
Let’s have a look at an example of inheritance.

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.

Below is the output.

 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:

1. Code Flexibility: Polymorphism allows different objects to be treated uniformly through a


common interface. This promotes code flexibility, as functions or algorithms can work with
objects of different types without needing to know their specific implementations.

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.

Let’s have a look at an example where we are implementing function overriding.


As you can see in the above example, there are three classes. Class Animal is the parent class,
Class Cheetah, which is the derived class, and Class Dolphin is again the derived class of Animal
class.

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

There are various advantages of object-oriented programming.

 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.

 Object-oriented programming is easy to implement.


IMPLEMENTATION OF OBJECT-ORIENTED PROGRAMMING (OOP) CONCEPTS USING
C++.

The main OOP concepts are:

1. Classes and Objects

2. Encapsulation

3. Inheritance

4. Polymorphism

1. Classes and Objects

A class is a blueprint for creating objects, and an object is an instance of a class.

#include <iostream>

#include <string>

class Dog {

public:

std::string name;

std::string breed;

Dog(std::string n, std::string b) : name(n), breed(b) {}

void bark() {

std::cout << name << " says woof!" << std::endl;

};

int main() {

Dog myDog("Buddy", "Golden Retriever");

myDog.bark(); // Outputs: Buddy says woof!

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:

BankAccount(std::string o, double b = 0.0) : owner(o), balance(b) {}

void deposit(double amount) {

balance += amount;

double getBalance() const {

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:

virtual void speak() {

std::cout << "Animal speaks" << std::endl;

};

class Cat : public Animal {

public:

void speak() override {

std::cout << "Cat meows" << std::endl;

};

int main() {

Cat myCat;

myCat.speak(); // Outputs: Cat meows

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:

virtual void speak() {

std::cout << "Chirp!" << std::endl;

};

class Dog {

public:

virtual void speak() {

std::cout << "Woof!" << std::endl;

};

void animalSound(Bird& animal) {

animal.speak();

int main() {

Dog myDog;

Bird myBird;

animalSound(myBird); // Outputs: Chirp!

animalSound(myDog); // Outputs: Woof!


return 0;

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.

C++ supports the following data types:

1. Primary or Built-in or Fundamental data type

2. Derived data types

3. User-defined data types


Data Types in C++ are Mainly Divided into 3 Types:

1. Primitive Data Types:

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

 Double 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

 Typedef defined Datatype

Primitive Data Types

 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.

// C++ Program to Demonstrate the correct size

// of various data types on your computer.

#include <iostream>

using namespace std;

int main()

cout << "Size of char : " << sizeof(char) << endl;

cout << "Size of int : " << sizeof(int) << endl;

cout << "Size of long : " << sizeof(long) << endl;

cout << "Size of float : " << sizeof(float) << endl;

cout << "Size of double : " << sizeof(double) << endl;

return 0;

Output

Size of char : 1

Size of int : 4

Size of long : 8

Size of float : 4
Size of double : 8

Time Complexity: O(1)

Space Complexity: O(1)

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.

Data type modifiers available in C++ are:

 Signed

 Unsigned

 Short

 Long

The below table summarizes the modified size and range of built-in datatypes when combined
with the type modifiers:

Data Type Size (in bytes) Range

short int 2 -32,768 to 32,767

unsigned short int 2 0 to 65,535


Data Type Size (in bytes) Range

unsigned int 4 0 to 4,294,967,295

int 4 -2,147,483,648 to 2,147,483,647

long int 4 -2,147,483,648 to 2,147,483,647

unsigned long int 4 0 to 4,294,967,295

long long int 8 -(2^63) to (2^63)-1

unsigned long long int 8 0 to 18,446,744,073,709,551,615

signed char 1 -128 to 127

unsigned char 1 0 to 255

float 4 -3.4×10^38 to 3.4×10^38

double 8 -1.7×10^308 to1.7×10^308

long double 12 -1.1×10^4932 to1.1×10^4932

wchar_t 2 or 4 1 wide character

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,

int num = 11;

num is an identifier.

Rules to Name of an Identifier in C++

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.

2. An identifier can only begin with a letter or an underscore only.


3. C++ has reserved keywords that cannot be used as identifiers since they have
predefined meanings in the language. For example, int cannot be used as an identifier
as it has already some predefined meaning in C++. Attempting to use these as
identifiers will result in a compilation error.

4. Identifier must be unique in its namespace.

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.

Example of Valid/Invalid Identifiers


Example of 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.

// C++ program to illustrate the identifiers

#include <iostream>

using namespace std;


// here Car_24 identifier is used to refer the below class

class Car_24 {

string Brand;

string model;

int year;

};

// calculateSum identifier is used to call the below

// function

void calculateSum(int a, int b)

int _sum = a + b;

cout << "The sum is: " << _sum << endl;

int main()

// identifiers used as variable names

int studentAge = 20;

double accountBalance = 1000.50;

string student_Name = "Karan";

calculateSum(2, 10);

return 0;

Output

The sum is: 12


CONTROL STRUCTURES

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

The if statement is a fundamental selection structure in C++. It executes a block of code if a


specified condition is true.

if (condition) {

// Code to be executed if the condition is true

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) {

// Code to be executed if the condition is true

} else {

// Code to be executed if the condition is false

3. nested if-else statement

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) {

// Code to be executed if condition1 is true


if (condition2) {

// Code to be executed if condition2 is true

} else {

// Code to be executed if condition2 is false

} else {

// Code to be executed if condition1 is false

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.

for (initialization; condition; 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.

for (element : collection) {

// Code to be executed for each element

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) {

break; // Exit the loop

// 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.

for (int i = 1; i <= 10; i++) {

if (i % 2 == 0) {

continue; // Skip even numbers

// Code to be executed for odd numbers

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

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 {

// Code that might throw an exception

} catch (exception_type1 e1) {

// Code to handle exception_type1

} catch (exception_type2 e2) {

// Code to handle exception_type2

} catch (...) {

// Code to handle any other type of exception

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++.

What is an Array in C++ Programming?

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.

Types of Arrays in C++

There are two types of array in C++, which are:

1. Single-dimensional array: It is a collection of elements of the same data type stored in a


contiguous block of memory.

2. Multi-dimensional array: It is an array that contains one or more arrays as its elements.

Array Initialization in C++

There are various ways to do this:

 Initialize at the time of declaration using {}.

int a[5] = {1, 2, 3, 4, 5};

 Initialize an array without specifying its size at declaration time.

int a[] = {1, 2, 3, 4, 5};

Though we haven't specified the size, the compiler understands the size as 5 due to the
initialization of 5 elements.

 Initialization by using the index of an element

 int marks[5];

 marks[0]=80; //the index of an array starts with 0.

 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

// store only 3 elements in the array

int a[5] = {1, 2, 3};

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.

Accessing Array Elements in C++

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>

using namespace std;

int main() {

int a[] = {25, 50, 75, 100};

cout << a[0] << '\n';

cout << a[1] << '\n';

cout << a[2] << '\n';

cout << a[3] << '\n';

return 0;

Run Code >>

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.

Changing the Elements of an Array in C++

To change the value of a specific element, refer to the index number:

Example

#include <iostream>

using namespace std;

int main()

int a[] = {25, 50, 75, 100, 45};

a[3] = 60;

cout << a[3] << '\n';

return 0;

Run Code >>

Output

60

Traversing an Array in C++

 To traverse an array, for loop is used.

Example

#include <iostream>

#include <string>

using namespace std;

int main() {

string fruits[5] = {"Apple", "Mango", "Banana", "Orange", "Grapes"};

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

cout << fruits[i] << '\n';

}
return 0;

Run Code >>

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>

using namespace std;

int main() {

string fruits[5] = {"Apple", "Mango", "Banana", "Orange", "Grapes"};

for (string i : fruits) {

cout << i << "\n";

return 0;

Run Code >>

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>

using namespace std;

int main() {

string fruits[5] = {"Apple", "Mango", "Banana", "Orange", "Grapes"};

for (int i = 0; i < sizeof(fruits) / sizeof(string); i++) {

cout << fruits[i] << '\n';

return 0;

Run Code >>

Output

Apple

Mango

Banana

Orange

Grapes

Input and Output Array Elements in C++

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>

using namespace std;


int main() {

int a[5];

cout << "Enter the values of an integer array:" << endl;

// Taking input and storing it in an array

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

cin >> a[i];

cout << "Displaying integers:" << endl;

// Printing elements of the array

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

cout << a[i] << endl;

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

Enter the values of an integer array:

Displaying integers:

1
2

Multidimensional Arrays in C++

1. Two Dimensional Arrays in C++

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

Example of a 2D array in C++

#include <iostream>

using namespace std;

int main()

int arr[6][6];

// Initialization

for (int i = 0; i < 6; i++) {

for (int j = 0; j < 6; j++) {

arr[i][j] = i + j;
}

for (int i = 0; i < 6; i++) {

for (int j = 0; j < 6; j++) {

cout << arr[i][j] << " ";

cout << endl;

return 0;

Run Code >>

Output

012345

123456

234567

345678

456789

5 6 7 8 9 10

2. Three Dimensional Arrays in C++

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,

 d: Number of 2D arrays or depth of array.


 r: Number of rows in each 2D array.

 c: Number of columns in each 2D array.

Example of a 3D array in C++

#include <iostream>

using namespace std;

int main()

int arr[3][3][3];

// initializing the array

for (int i = 1; i < 4; i++) {

for (int j = 1; j < 4; j++) {

for (int k = 1; k < 4; k++) {

arr[i][j][k] = i + j + k;

for (int i = 1; i < 4; i++) {

cout << i << "st layer:" << endl;

for (int j = 1; j < 4; j++) {

for (int k = 1; k < 4; k++) {

cout << arr[i][j][k] << " ";

cout << endl;

cout << endl;


}

return 0;

Run Code >>

Output

1st layer:

345

456

567

2st layer:

456

567

678

3st layer:

567

678

789

Advantages of an Array in C++

 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.

 Flexibility: Arrays in C++ can be used to store different types of data,


including integers, characters, and strings.
 Easy to implement algorithms: Many algorithms in computer science use arrays, making
it easy to implement these algorithms in C++.

 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.

 Easy to pass to functions: Arrays can be easily passed as arguments to functions in


C++, making it easy to manipulate large amounts of data efficiently.

Disadvantages of an Array in C++

 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

What Are C++ 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.

Why Use Functions in C++?

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.

Now, have a look at the syntax of C++ functions.

Function Syntax

The syntax for creating a function is as follows:

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.

Types of Functions in C++

There are two types of functions in C++

 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.

You can put them down as the following types:

 No argument and no return value

 No argument but the return value

 Argument but no return value

 Argument and return value

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.

Function Call Methods

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.

Below is the output of the above example.


TEMPLATE

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 ‘typename’. 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().

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

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);

a.print();

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 256 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

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 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++

// 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++

// 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:

// Parameterized constructor
student(string n, T m)

: student_name(n)

, total_marks(m)

}
void getinfo()

// printing the details of the student


cout << "STUDENT NAME: " << student_name << endl;

cout << "TOTAL MARKS: " << total_marks << endl;

cout << "Type ID: " << typeid(total_marks).name()

<< endl;

};

int main()

student s1("Vipul", 100); // Deduces student<int>

student s2("Yash", 98.5); // Deduces student<double>

s1.getinfo();

s2.getinfo();

return 0;

Output

STUDENT NAME: Vipul


TOTAL MARKS: 100
Type ID: i
STUDENT NAME: Yash
TOTAL MARKS: 98.5
Type ID: d

Here, i means int, and d means double.


Variable Templates

Variable templates are used to create parameterized variables.

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.

Need of Variable Templates

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.

Syntax of Variable Templates

Variable templates are defined using the following syntax:

template <parameters> variable-declaration

where,

 parameter: It is the list of template parameters.

 variable-declaration: Declaration of the variable.

Let’s take a look at a simple example of a variable template that defines the constant e (euler):

template <class T>

constexpr T e = T(2.718281828459045); //a variable template

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.

Example of Variable Template

// C++ program to illustrate the use of variable template

#include <iostream>

using namespace std;

// declaring thhe variable template

template <class T> constexpr T e = T(2.718281828459045);


int main()

cout << "Integer Type of e: " << e<int> << endl;

cout << "Float Type of e: " << e<float> << endl;

return 0;

Output

Integer Type of e: 2

Float Type of e: 2.71828

Variable Templates in Class

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

// C++ program to illustrate the use of static data member

// template

#include <iostream>

using namespace std;

class limits {

public:

// static data member template declaration

template <typename T> static const T min;

};

// definition
template <typename T> const T limits::min = T(10.24);

int main()

cout << limits::min<int> << endl;

cout << limits::min<float>;

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.

Implicit Instantiation of Variable Templates

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.

Example of Implicit Instatiation

In this example. we will take a constant pi and will not specify the type of the constant.

// C++ Program to illustrate Variable Templates

#include <iostream>

using namespace std;

// Variable template for pi

template <class T> constexpr T pi = T(3.1415926535897L);

// Function template that calculates the area of a circle


template <class T> T circular_area(T r)

return pi<T> * r * r;

int main()

// Example 1: Using pi with int

int radius_int = 10;

int area_int = circular_area(radius_int);

cout << "Area of circle with radius " << radius_int

<< " is " << area_int << endl;

// Example 2: Using pi with double

double radius_double = 10.0;

double area_double = circular_area(radius_double);

cout << "Area of circle with radius " << radius_double

<< " is " << area_double << endl;

return 0;

Output

Area of circle with radius 10 is 300

Area of circle with radius 10 is 314.159

Applications of Variable Templates

Following are some of the major application of the variable templates:

1. It is used to define the type dependent constants.

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.

What are Pointers in C++?

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.

Use of Pointers in C++

 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++.

 Arrays, Functions, and Structures - Pointers in the c ++ programming language are


widely used in arrays, structures, and functions. It reduces the code and improves the
performance of that particular program.

Pointer Declaration 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;

 datatype* var_name; //preferred syntax

Example

 int *a;//pointer to int

 int* a;//pointer to int

Pointer Initialization in C++

The procedure of initializing a pointer is where we give the memory address of another variable
using the & (address of) operator.
Example

#include <iostream>

using namespace std;

int main() {

int x = 42; // Declare and initialize an integer variable 'x'

// declare pointer variable 'ptr' and initialize it with the address of 'x'

int *ptr = &x;

// print value of x

cout << "x = " << x << endl;

// print address of x

cout << "Address of x (&x) = " << &x << endl

<< endl;

// print pointer ptr

cout << "ptr = " << ptr << endl;

// print the content of the address ptr points to

cout << "Content of the address pointed to by ptr (*ptr) = " << *ptr << endl;

return 0;

In this C++ code,

 an integer variable, x is initialized to 42

 a pointer, ptr is created to hold x's address in memory.


Output

x = 42

Address of x (&x) = 0x7ffeb5f7b3c4

ptr = 0x7ffeb5f7b3c4

Content of the address pointed to by ptr (*ptr) = 42

* used in the above example can confuse you. It serves two purposes:

 When used in the declaration (int *a), it creates a pointer variable.

 When not used in the declaration (*a), it acts as a dereference operator.

Modifying Values Pointed by Pointers

Example

#include <iostream>

using namespace std;

int main() {

int x = 42; // Declare and initialize an integer variable 'x'

// declare pointer variable 'ptr' and initialize it with the address of 'x'

int *ptr = &x;

// print value of x

cout << "x = " << x << endl;

// print *ptr

cout << "*ptr = " << *tr << endl

<< endl;

cout << "Changing value of x to 70:" << endl;


// change value of x to 70

x = 70;

// print x

cout << "x = " << x << endl;

// print *ptr

cout << "*ptr = " << *ptr << endl

<< endl;

cout << "Changing value of *ptr to 60:" << endl;

// change value of ptr to 60

*ptr = 60;

// print x

cout << "x = " << x << endl;

// print *ptr

cout << "*ptr = " << *ptr << endl;

return 0;

Run Code >>

In the above C++ code in C++ Compiler, ptr points to the address of x. Therefore

 when value of x is changed, *ptr also gets changed

 when *ptr is modified, value of x also gets modified

Output

x = 42

*ptr = 42
Changing value of x to 70:

x = 70

*ptr = 70

Changing value of *ptr to 60:

x = 60

*ptr = 60

Types of Pointers in C++

1. NULL Pointer

A NULL pointer indicates that it has not been initialized and points to nowhere in memory.

Syntax

int* nullPointer = NULL;

Example of NULL Pointers

#include <iostream>

using namespace std;

int main() {

int *ptr = nullptr;

if (ptr == nullptr) {

cout << "This pointer is called the null pointer." << endl;

return 0;

Output

This pointer is called the null pointer.

2. Integer Pointers
The memory location of an integer variable is stored in integer pointers.

Syntax

int* intPointer;

Example of Integer Pointers in C++

#include <iostream>

int main() {

// Declare an integer variable

int num = 42;

// Declare an integer pointer and initialize it with the address of the variable

int *ptr = #

// Access the value using the pointer

std::cout << "Value of num: " << *ptr << std::endl;

// Modify the value using the pointer

*ptr = 100;

// Display the modified value

std::cout << "Modified value of num: " << num << std::endl;

return 0;

Output

Value of num: 42

Modified value of num: 100


3. Array Pointer

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];

int* arrPointer = arr;

Example of Array Pointers in C++

#include <iostream>

int main() {

int arr[] = {10, 20, 30, 40, 50};

int* p = arr; // Array pointer to the first element of arr

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

std::cout << *(p + i) << " "; // Accessing array elements through pointer arithmetic

std::cout << std::endl;

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

int (*funcPointer)(int, int);


Example of Function Pointers in C++

#include <iostream>

// Define two functions with the same signature

int add(int a, int b) {

return a + b;

int subtract(int a, int b) {

return a - b;

int main() {

// Declare a function pointer with the same signature as the functions

int (*operation)(int, int);

// Initialize the function pointer with the address of the add function

operation = add;

// Use the function pointer to call the add function

int result = operation(10, 5);

std::cout << "Result of addition: " << result << std::endl;

// Reassign the function pointer to the subtract function

operation = subtract;

// Use the function pointer to call the subtract function

result = operation(10, 5);


std::cout << "Result of subtraction: " << result << std::endl;

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;

Example of void Pointers in C++

#include <iostream>

using namespace std;

int main() {

int x = 105;

float y = 89;

void *p = nullptr;

p = &x;

cout << "Integer value: " << *(static_cast(p)) << endl;

p = &y;

cout << "Float value: " << *(static_cast(p)) << endl;

return 0;
}

Output

Integer value: 105

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;

};

struct MyStruct* structPointer;

Example of Structure Pointer

#include <iostream>

#include <cstring>

using namespace std;

struct Employee {

int id;

char name[20];

};

int main() {

Employee *ptr = new Employee; // Dynamically allocate memory for one Employee struct

// Access struct members through pointer

ptr->id = 789;
strcpy(ptr->name, "Sourav Kumar");

cout << "Employee ID: " << ptr->id << endl;

cout << "Employee Name: " << ptr->name << endl;

delete ptr;

return 0;

Output

Employee ID: 789

Employee Name: Sourav Kumar

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

int** ptr; // Declaration of a double pointer to an integer

Example of pointer to pointer in C++

#include <iostream>

int main() {

int value = 50;

int* singlePtr = &value; // Pointer to an integer

int** doublePtr = &singlePtr; // Double pointer to an integer pointer

std::cout << "Value: " << value << std::endl;

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

Single pointer points to value: 50

Double pointer points to single pointer: 50

Advantages of using Pointers in C +

Advantages to using pointers in C ++

 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

For achieving file handling we need to follow the following steps:-

STEP 1-Naming a file


STEP 2-Opening a file
STEP 3-Writing data into the file
STEP 4-Reading data from the file
STEP 5-Closing a file.

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”.

Classes for File stream operations :-

The I/O system of C++ contains a set of classes which define the file handling methods.

These include ifstream, ofstream and fstream classes.

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:-

 ios stands for input output stream.

 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:-

 istream stands for input stream.

 This class is derived from the class ‘ios’.

 This class handle input stream.

 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:-

 ostream stands for output stream.

 This class is derived from the class ‘ios’.

 This class handle output stream.

 The insertion operator(<<) is overloaded in this class to handle output streams to files
from the program execution.

 This class declares output functions such as put() and write().

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.

 This class contains open() and close() function.

6. ifstream:-

 This class provides input operations.

 It contains open() function with default input mode.

 Inherits the functions get(), getline(), read(), seekg() and tellg() functions from the
istream.

7. ofstream:-

 This class provides output operations.

 It contains open() function with default output mode.


 Inherits the functions put(), write(), seekp() and tellp() functions from the ostream.

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:-

 Its purpose is to set the file buffers to read and write.

 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.

ofstream: Stream class to write on files


ifstream: Stream class to read from files
fstream: Stream class to both read and write from/to files.

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.

Open File by using constructor


ifstream (const char* filename, ios_base::openmode mode = ios_base::in);
ifstream fin(filename, openmode) by default openmode = ios::in
ifstream fin(“filename”);
Open File by using open method
Calling of default constructor
ifstream fin;
fin.open(filename, openmode)
fin.open(“filename”);

Modes :

Member
Constant Stands For Access

File open for reading: the internal stream buffer supports


ios::in input
input operations.

File open for writing: the internal stream buffer supports


ios::out output
output operations.

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.

All output operations happen at the end of the file,


ios::app append
appending to its existing contents.

Any contents that existed in the file before it is open are


ios::trunc truncate
discarded.

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

Fstream ios::in | ios::out

Problem Statement : To read and write a File in C++.


Examples:

Input :
Welcome in Kenya. Best way to learn things.
-1
Output :
Welcome in Kenya. Best way to learn things.

Below is the implementation by using ifstream & ofstream classes.

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>

/* fstream header file for ifstream, ofstream,


fstream classes */
#include <fstream>

using namespace std;

// Driver Code
int main()

// Creation of ofstream class object


ofstream fout;

string line;

// by default ios::out mode, automatically deletes


// the content of file. To append the content, open in ios:app
// fout.open("sample.txt", ios::app)
fout.open("sample.txt");

// Execute a loop If file successfully opened


while (fout) {

// Read a Line from standard input


getline(cin, line);

// Press -1 to exit
if (line == "-1")

break;

// Write line in file


fout << line << endl;

// Close the File


fout.close();

// Creation of ifstream class object to read the file


ifstream fin;
// by default open mode = ios::in mode
fin.open("sample.txt");

// Execute a loop until EOF (End of File)


while (getline(fin, line)) {

// Print line (read from file) in Console


cout << line << endl;

// Close the file


fin.close();

return 0;

Time Complexity: O(n)


Auxiliary Space: O(1)

Below is the implementation by using fstream class.

C++

/* File Handling with C++ using fstream class object */


/* To write the Content in File */
/* Then to read the content of file*/
#include <iostream>

/* fstream header file for ifstream, ofstream,


fstream classes */
#include <fstream>

using namespace std;


// Driver Code
int main()

// Creation of fstream class object


fstream fio;

string line;

// by default openmode = ios::in|ios::out mode


// Automatically overwrites the content of file, To append
// the content, open in ios:app
// fio.open("sample.txt", ios::in|ios::out|ios::app)
// ios::trunc mode delete all content before open
fio.open("sample.txt", ios::trunc | ios::out | ios::in);

// Execute a loop If file successfully Opened


while (fio) {

// Read a Line from standard input


getline(cin, line);

// Press -1 to exit
if (line == "-1")

break;

// Write line in file


fio << line << endl;

}
// Execute a loop until EOF (End of File)
// point read pointer at beginning of file
fio.seekg(0, ios::beg);

while (fio) {

// Read a Line from File


getline(fio, line);

// Print line in Console


cout << line << endl;

// Close the file


fio.close();

return 0;

Time Complexity: O(n)


Auxiliary Space: O(1)

C++

// Q: write a single file handling program in c++ to reading


// and writing data on a file.

// Include necessary header files


#include <fstream>

#include <iostream>

#include <string>
// Use the standard namespace
using namespace std;

int main()

// Create an output file stream object


ofstream fout;

// Open a file named "NewFile.txt" for writing


fout.open("NewFile.txt");

// Check if the file opened successfully


if (!fout) {

// Print an error message if the file couldn't be


// opened
cerr << "Error opening file!" << endl;

// Return 1 to indicate failure


return 1;

// Declare a string variable to hold each line of text


string line;

// Initialize a counter to limit input to 5 lines


int i = 0;

// Prompt the user to enter 5 lines of text


cout << "Enter 5 lines of text:" << endl;

// Loop to read 5 lines of input from the user


while (i < 5) {
// Read a line of text from standard input
getline(cin, line);

// Write the line of text to the file


fout << line << endl;

// Increment the counter


i += 1;

// Close the file after writing


fout.close();

// Print a success message


cout << "Text successfully written to NewFile.txt"

<< endl;

// Return 0 to indicate successful execution


return 0;

Output

Enter 5 lines of text:

#include<iostream>

#include<fstream>

using namespace std;

main()

{
int rno,fee;

char name[50];

ifstream fin("d:/student.doc");

fin>>rno>>name>>fee; //read data from the file student

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.

What is a Constructor in C++?

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.
}

};

Characteristics of Constructors in C++

 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.

Types of Constructors in C++

There are four types of constructors in C++:

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:

//default constructor without any arguments


Employee :: Employee()

Example:

#include <bits/stdc++.h>

using namespace std;

class Employee {

public:

int age;

// Default constructor.
Employee() {

/* Data member is defined with the help of the


default constructor.*/
age = 50;

};

int main() {

// Object of class Employee declared.


Employee e1;

// Prints value assigned by default constructor.


cout << e1.age;

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>

using namespace std;

class Employee {

public:

int age;

// Default constructor not defined.


// Compiler calls default constructor.
};

int main() {

// Object e1 declared.
Employee e1;

cout << e1.age;

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>

using namespace std;

class Employee {

public:

int age;

// Parameterized constructor
Employee(int x) {

/* Age assigned to value passed as an argument


while object declaration.*/
age = x;

};

int main() {

/* Object c1 declared with argument 40, which


gets assigned to age.*/
Employee c1(40);

Employee c2(30);

Employee c3(50);

cout << c1.age << "\n";

cout << c2.age << "\n";

cout << c3.age << "\n";

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>

using namespace std;

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() {

cout << "Salary: " << salary << endl;

cout << "Years of experience: " << experience << endl;

};

// main function
int main() {

// Parameterized constructor
Employee employee1(34000, 2);

// Copy constructor
Employee employee2 = employee1;

cout << "Employee1 using parameterized constructor : \n";

employee1.display();

cout << "Employee2 using copy constructor : \n";

employee2.display();

return 0;

Output:

Employee1 using the parameterized constructor :

Salary: 34000

Years of experience: 2

Employee2 using copy constructor :


Salary: 34000

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>

using namespace std;

class Employee {

int* due_projects;

public:

// Default constructor.
Employee() {

// Allocating memory at run time.


due_projects = new int;

*due_projects = 0;

// Parameterized constructor.
Employee(int x) {

due_projects = new int;


*due_projects = x;

void display() {

cout << *due_projects << endl;

};

// Main function
int main() {

// Default constructor would be called.


Employee employee1 = Employee();

cout << "Due projects for employee1:\n";

employee1.display();

// Parameterized constructor would be called.


Employee employee2 = Employee(10);

cout << "Due projects for employee2:\n";

employee2.display();

return 0;

Output:

Due projects for employee1:

Due projects for employee2:

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.

What is a Destructor in C++?

A Destructor is a member function that is instantaneously called whenever an object is


destroyed. The destructor is called automatically by the compiler when the object goes out of
scope, i.e., when a function ends, the local objects created within it are also destroyed. The
destructor has the same name as the class name, but the name is preceded by a tilde(~). A
destructor has no return type and receives no parameters.

Syntax of Destructor:

class scaler {

public:

//constructor
scaler();

//destructor
~scaler();

};

Characteristics of a Destructor in C++

 A destructor deallocates memory occupied by the object when it’s deleted.

 A destructor cannot be overloaded. In function overloading, functions are declared with


the same name in the same scope, except that each function has a different number of
arguments and different definitions. But in a class, there is always a single destructor
that does not accept any parameters. Hence, a destructor cannot be overloaded.

 A destructor is always called in the reverse order of the constructor. In C++, variables
and objects are allocated on the Stack. The Stack follows the LIFO (Last-In-First-Out)
pattern. So, the deallocation of memory and destruction is always carried out in the
reverse order of allocation and construction. This can be seen in the code below.

 A destructor can be written anywhere in the class definition. But to bring an amount
order to the code, a destructor is always defined at the end of the class definition.
Implementation of Constructors and Destructors in C++

#include <iostream>

using namespace std;

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) {

// Creating an object of Department.


Department d1;

// Creating an object of Employee.


Employee e2;

return 0;

Output:

Constructor Invoked for Department class

Constructor Invoked for Employee class

Destructor Invoked for Employee class

Destructor Invoked for Department class

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.

Difference Between Constructors and Destructors

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.

Destructor cannot accept any


3 Constructor can receive parameters.
parameters.

Constructor is used to initialize an object of the class


While destructor is used to deallocate
4 and assign values to data members corresponding to
the memory of an object of a class.
the class.

In a class, there is always a single


5 There can be multiple constructors for the same class.
destructor.

6 Constructor can be overloaded. Destructor can’t be overloaded.


ABSTRACT CLASSES

An interface describes the behavior or capabilities of a C++ class without committing to a


particular implementation of that class.

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:

// pure virtual function

virtual double getVolume() = 0;

private:

double length; // Length of a box

double breadth; // Breadth of a box

double height; // Height of a box

};

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.

Abstract Class Example

Consider the following example where parent class provides an interface to the base class to
implement a function called getArea() –
#include <iostream>

using namespace std;

// Base class

class Shape {

public:

// pure virtual function providing interface framework.

virtual int getArea() = 0;

void setWidth(int w) {

width = w;

void setHeight(int h) {

height = h;

protected:

int width;

int height;

};

// Derived classes

class Rectangle: public Shape {

public:

int getArea() {

return (width * height);

};

class Triangle: public Shape {


public:

int getArea() {

return (width * height)/2;

};

int main(void) {

Rectangle Rect;

Triangle Tri;

Rect.setWidth(5);

Rect.setHeight(7);

// Print the area of the object.

cout << "Total Rectangle area: " << Rect.getArea() << endl;

Tri.setWidth(5);

Tri.setHeight(7);

// Print the area of the object.

cout << "Total Triangle area: " << Tri.getArea() << endl;

return 0;

When the above code is compiled and executed, it produces the following result −

Total Rectangle area: 35

Total Triangle area: 17

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.

 catch − A program catches an exception with an exception handler at the place in a


program where you want to handle the problem. The catch keyword indicates the
catching of an exception.

 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

Following is an example of throwing an exception when dividing by zero condition occurs −

double division(int a, int b) {

if( b == 0 ) {

throw "Division by zero condition!";

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 ) {

// code to handle ExceptionName exception

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(...) {

// code to handle any exception

Example

The following is an example, which throws a division by zero exception and we catch it in catch
block.

#include <iostream>

using namespace std;


double division(int a, int b) {

if( b == 0 ) {

throw "Division by zero condition!";

return (a/b);

int main () {

int x = 50;

int y = 0;

double z = 0;

try {

z = division(x, y);

cout << z << endl;

} catch (const char* msg) {

cerr << msg << endl;

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 −

Division by zero condition!

C++ Standard Exceptions

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 −

Sr.No Exception & Description

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>

using namespace std;

struct MyException : public exception {

const char * what () const throw () {

return "C++ Exception";

};

int main() {

try {

throw MyException();

} catch(MyException& e) {

std::cout << "MyException caught" << std::endl;

std::cout << e.what() << std::endl;

} catch(std::exception& e) {

//Other errors

This would produce the following result −

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.

In C++, we can achieve concurrency using threads:

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.

Errors and Risks Associated with Concurrency

Concurrent multithreading applications need to be carefully designed as it is prone to many


errors leading to undefined behaviour. Some of these errors are:

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 in C++

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.

3. Futures and Promises

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.

Example: Concurrent C++ Program

C++

// C++ Program to illustrate the use of multiple thread


#include <iostream>

#include <mutex>

#include <thread>

#include <vector>

using namespace std;

// shared resource that will be updated


int sum = 0;

// mutex lock for synchronization (althout application can


// work just fine without it in this case, it is still used
// for demonstration)
mutex lck;
// function to get sum of the vector elements in the given
// range
void getSum(const vector<int>& v, int start, int end)

// a predefined wrapper over mutex lock


lock_guard<mutex> mu(lck);

// performing operation
for (int i = start; i <= end; i++) {

sum += v[i];

// mu object will automatically release the mutex lock


// lck when destroyed
}

// driver code
int main()

// vector with 10 elements


vector<int> v

= { 2, 4654, 321, 65, 32, 165, 432, 2, 16, 54 };

// finding mid point


int mid = v.size() / 2;

// creating two threads


// one thread to add first half elements
thread t1(getSum, v, 0, mid);
// other thread to add second half elements
thread t2(getSum, v, mid + 1, v.size() - 1);

// waiting for threads to finish


t1.join();

t2.join();

cout << "Array Elements: ";

for (auto i : v) {

cout << i << " ";

cout << endl;

// printing sum
cout << "Sum: " << sum;

return 0;

Output

Array Elements: 2 4654 321 65 32 165 432 2 16 54


Sum: 6048

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

Processing multiple tasks in Simultaneous execution of


the overlapping time the multiple tasks on
Definition intervals different threads.

Making progress on more Performing multiple tasks at


Focus than one task at time. exactly the same time.

Single processor or core at Multiple processors or cores


Processor Usage one at once

Tasks often work the


Tasks may or may not
independently or
interact with the each other
Task Interaction communicate

Suitable and faster for small


Suitable for large tasks for
tasks as it doesn’t have
which the thread setup
overhead due to being in
overhead costs is negligible.
Use Cases the single core.

Benefits of Concurrency

The concurrency provides a lot of benefits to the programmer and application:

 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.

You might also like