KEMBAR78
C++ HandBook | PDF | C++ | Data Type
0% found this document useful (0 votes)
32 views113 pages

C++ HandBook

C++ is a cross-platform, high-performance programming language developed as an extension of C, offering control over system resources and memory. It is widely used in operating systems, GUIs, and embedded systems, and features object-oriented programming for code reuse and structure. The document covers C++ syntax, variables, data types, operators, user input, and control structures, providing examples and explanations for each concept.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views113 pages

C++ HandBook

C++ is a cross-platform, high-performance programming language developed as an extension of C, offering control over system resources and memory. It is widely used in operating systems, GUIs, and embedded systems, and features object-oriented programming for code reuse and structure. The document covers C++ syntax, variables, data types, operators, user input, and control structures, providing examples and explanations for each concept.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 113

C++ Introduction

What is C++?
C++ is a cross-platform language that can be used to create high-
performance applications.

C++ was developed by Bjarne Stroustrup, as an extension to the C


language.

C++ gives programmers a high level of control over system resources and
memory.

Why Use C++


C++ is one of the world's most popular programming languages.

C++ can be found in today's operating systems, Graphical User Interfaces,


and embedded systems.

C++ is an object-oriented programming language which gives a clear


structure to programs and allows code to be reused, lowering development
costs.

C++ is portable and can be used to develop applications that can be adapted
to multiple platforms.

C++ is fun and easy to learn!

As C++ is close to C, C# and Java, it makes it easy for programmers to


switch to C++ or vice versa.

C++ Install IDE


An IDE (Integrated Development Environment) is used to edit AND compile
the code.

Popular IDE's include Code::Blocks, Eclipse, and Visual Studio. These are all
free, and they can be used to both edit and debug C++ code.

C++ Syntax
Let's break up the following code to understand it better:
Example
#include <iostream>
using namespace std;

int main() {
cout << "Vendant!”
return 0;
}

Example explained
Line 1: #include <iostream> #include “Math.h” is a header file
library that lets us work with input and output objects, such as cout (used in
line 5). Header files add functionality to C++ programs.

Line 2: using namespace std means that we can use names for objects
and variables from the standard library.

Don't worry if you don't understand how #include <iostream> and using
namespace std works. Just think of it as something that (almost) always
appears in your program.

Line 3: A blank line. C++ ignores white space. But we use it to make the
code more readable.

Line 4: Another thing that always appear in a C++ program, is int main().
This is called a function. Any code inside its curly brackets {} will be
executed.

Line 5: cout (pronounced "see-out") is an object used together with


the insertion operator (<<) to output/print text. In our example it will output
"Hello World".

Note: Every C++ statement ends with a semicolon ;.

Note: The body of int main() could also been written as:
int main () { cout << "Hello World! "; return 0; }

Remember: The compiler ignores white spaces. However, multiple lines


makes the code more readable.

Line 6: return 0 ends the main function.

Line 7: Do not forget to add the closing curly bracket } to actually end the
main function.
C++ Comments
// This is my single line comment
/* Here I can Add multiple line comment
So user can easily understand the use of The below code or
Use of the function */

C++ Variables
Variables are containers for storing data values.

In C++, there are different types of variables (defined with different


keywords), for example:

 int - stores integers (whole numbers), without decimals like 25, 24,90
 double - stores floating point numbers, with decimals, such as 19.99 or
-1.99
 char - stores single characters, such as 'a' or 'B'. Char values are
surrounded by single quotes
 string - stores text, such as "Hello World". String values are
surrounded by double quotes
 bool - stores values with two states: true or false

Syntax
type variableName = value;
int Value = 5; // Integer (whole number without
decimals)
double myFloatNum = 5.99; // Floating point number (with
decimals)
char myLetter = 'D'; // Character
string myText = "Hello"; // String (text)
bool myBoolean = true; // Boolean (true or false)

int x = 5, y = 6, z = 50; // Multiple variables


cout << x + y + z;

Constants Const Keyword


const int myNum = 15; // myNum will always be 15
myNum = 10; // error: assignment of read-only variable 'myNum'
You should always declare the variable as constant when you have values
that are unlikely to change:

C++ User Input


You have already learned that cout is used to output (print) values. Now we
will use cin to get user input.

cin is a predefined variable that reads data from the keyboard with the
extraction operator (>>).

In the following example, the user can input a number, which is stored in the
variable x. Then we print the value of x:

Example
int x;
cout << "Type a number: "; // Type a number and press enter
cin >> x; // Get user input from the keyboard
cout << "Your number is: " << x; // Display the input value

Good To Know

cout is pronounced "see-out". Used for output, and uses the insertion
operator (<<)

cin is pronounced "see-in". Used for input, and uses the extraction
operator (>>)

C++ Data Types


As explained in the Variables chapter, a variable in C++ must be a specified
data type:

Example
int myNum = 5; // Integer (whole number)
float myFloatNum = 5.99; // Floating point number
double myDoubleNum = 9.98; // Floating point number
char myLetter = 'D'; // Character
bool myBoolean = true; // Boolean
string myText = "Hello"; // String

Try it Yourself »
Basic Data Types
The data type specifies the size and type of information the variable will
store:

Data Type Size Description

boolean 1 byte Stores true or false values

char 1 byte Stores a single character/letter/number, or ASCII values

int 2 or 4 bytes Stores whole numbers, without decimals

float 4 bytes Stores fractional numbers, containing one or more decimals. Sufficient for storing 7
decimal digits

double 8 bytes Stores fractional numbers, containing one or more decimals. Sufficient for storing 15
decimal digits

C++ Operators
Operators are used to perform operations on variables and values.

In the example below, we use the + operator to add together two values:

Example
int x = 100 + 50;
Although the + operator is often used to add together two values, like in the
example above, it can also be used to add together a variable and a value, or
a variable and another variable:

Example
int sum1 = 100 + 50; // 150 (100 + 50)
int sum2 = sum1 + 250; // 400 (150 + 250)
int sum3 = sum2 + sum2; // 800 (400 + 400)

Try it Yourself »

C++ divides the operators into the following groups:

 Arithmetic operators
 Assignment operators
 Comparison operators
 Logical operators
 Bitwise operators

Arithmetic Operators
Arithmetic operators are used to perform common mathematical operations.

operat descriptio
or n
+ addition
- subtraction
multiplicati
*
on
/ division
% modulo
Compound assignment (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |
=)
Compound assignment operators modify the current value of a
variable by performing an operation on it. They are equivalent to
assigning the result of an operation to the first operand:

expression equivalent to...


y += x; y = y + x;
x -= 5; x = x - 5;
x /= y; x = x / y;
price *= units price = price *
+ 1; (units+1);

and the same for all other compound assignment operators. For
example:

// compound assignment operators


#include <iostream>
using namespace std;

int main ()
{
int a, b=3;
a = b;
a+=2; // equivalent to a=a+2
cout << a;

Increment and decrement (++, --)


Some expression can be shortened even more: the increase
operator (++) and the decrease operator (--) increase or reduce
by one the value stored in a variable. They are equivalent
to +=1 and to -=1, respectively. Thus:

1 ++x;
2 x+=1;
3 x=x+1
;
Relational and comparison operators ( ==, !=, >, <, >=, <= )
Two expressions can be compared using relational and equality
operators. For example, to know if two values are equal or if one
is greater than the other.

The result of such an operation is either true or false (i.e., a


Boolean value).
The relational operators in C++ are:

operat
description
or
== Equal to
!= Not equal to
< Less than
> Greater than
Less than or equal
<=
to
Greater than or
>=
equal to

Here there are some examples:

1 (7 == 5) // evaluates to
2 false
3 (5 > 4) // evaluates to
4 true
5 (3 != 2) // evaluates to
true
(6 >= 6) // evaluates to
true
(5 < 5) // evaluates to
false

Of course, it's not just numeric constants that can be compared,


but just any value, including, of course, variables. Suppose
that a=2, b=3 and c=6, then:

1 (a == 5) // evaluates to false, since a is not


2 equal to 5
3 (a*b >= c) // evaluates to true, since (2*3 >= 6)
4 is true
(b+4 > a*c) // evaluates to false, since (3+4 >
2*6) is false
((b=2) == a) // evaluates to true
Logical operators ( !, &&, || )
The operator ! is the C++ operator for the Boolean operation
NOT. It has only one operand, to its right, and inverts it,
producing false if its operand is true, and true if its operand
is false. Basically, it returns the opposite Boolean value of
evaluating its operand. For example:

1 !(5 == 5) // evaluates to false because the expression at its right


2 (5 == 5) is true
3 !(6 <= 4) // evaluates to true because (6 <= 4) would be false
4 !true // evaluates to false
!false // evaluates to true

The logical operators && and || are used when evaluating two
expressions to obtain a single relational result. The
operator && corresponds to the Boolean logical operation AND,
which yields true if both its operands are true,
and false otherwise. The following panel shows the result of
operator && evaluating the expression a&&b:

&& OPERATOR
(and)
a b a && b
true true true
true false false
false true false
false false false

The operator || corresponds to the Boolean logical operation OR,


which yields true if either of its operands is true, thus being false
only when both operands are false. Here are the possible results
of a||b:

|| OPERATOR
(or)
a ||
a b
b
true true true
fals
true true
e
fals
true true
e
fals fals
false
e e

For example:
1 ( (5 == 5) && (3 > 6) ) // evaluates to false
2 ( true && false )
( (5 == 5) || (3 > 6) ) // evaluates to true ( true
|| false )

Conditional ternary operator ( ? )


The conditional operator evaluates an expression, returning one
value if that expression evaluates to true, and a different one if
the expression evaluates as false. Its syntax is:

condition ? result1 : result2

If condition is true, the entire expression evaluates to result1,


and otherwise to result2.

1 7==5 ? 4 : 3 // evaluates to 3, since 7 is not equal to 5.


2 7==5+2 ? 4 : 3 // evaluates to 4, since 7 is equal to 5+2.
3 5>3 ? a : b // evaluates to the value of a, since 5 is
4 greater than 3.
a>b ? a : b // evaluates to whichever is greater, a or b.

// conditional operator
#include <iostream>
using namespace std;

int main ()
{
int a,b,c;
cin >> a ;
cin >> b;
a=2;
b=7;
c = (a>b) ? a : b;

cout << c << '\n';


}

C++ Strings
Strings are used for storing text.

A string variable contains a collection of characters surrounded by double


quotes:

// Include the string library


#include <string>

// Create a string variable


string Name = "Hello";

String Concatenation
The + operator can be used between strings to add them together to make a
new string. This is called concatenation:

Example
string firstName = "John ";
string lastName = "Doe";
string fullName = firstName + lastName;
cout << fullName;

In the example above, we added a space after firstName to create a space


between John and Doe on output. However, you could also add a space with
quotes (" " or ' '):

Example
string firstName = "John";
string lastName = "Doe";
string fullName = firstName + " " + lastName;
cout << fullName;
Append
A string in C++ is actually an object, which contain functions that can
perform certain operations on strings. For example, you can also concatenate
strings with the append() function:

Example
string firstName = "John ";
string lastName = "Doe";
string fullName = firstName.append(lastName);
cout << fullName;

String Length
To get the length of a string, use the length() function:

Example
string txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << "The length of the txt string is: " << txt.length();

Tip: You might see some C++ programs that use the size() function to get
the length of a string. This is just an alias of length(). It is completely up to
you if you want to use length() or size():

Example
string txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
cout << "The length of the txt string is: " << txt.size();

Access Strings
You can access the characters in a string by referring to its index number
inside square brackets [].

This example prints the first character in myString:

Example
string myString = "Hello";
cout << myString[0];
// Outputs H
Note: String indexes start with 0: [0] is the first character. [1] is the second
character, etc.

This example prints the second character in myString:

Example
string myString = "Hello";
cout << myString[1];
// Outputs e

Example
string myString = "Hello";
myString[0] = 'J';
cout << myString;
// Outputs Jello instead of Hello

#include <iostream>
#include <string>

int main() {
std::string greeting = "Hello";
std::cout << greeting;
return 0;
}

C++ Conditions and If


Statements
C++ supports the usual logical conditions from mathematics:

 Less than: a < b


 Less than or equal to: a <= b
 Greater than: a > b
 Greater than or equal to: a >= b
 Equal to a == b
 Not Equal to: a != b

Syntax
if (condition) {
// block of code to be executed if the condition is true
}
Example
int x = 20;
int y = 18;
if (x > y) {
cout << "x is greater than y";
}

The else Statement


Use the else statement to specify a block of code to be executed if the
condition is false.

Syntax
if (condition) {
// block of code to be executed if the condition is true
} else {
// block of code to be executed if the condition is false
}

Example
int time = 20;
if (time < 18) {
cout << "Good day.";
} else {
cout << "Good evening.";
}

The else if Statement


Use the else if statement to specify a new condition if the first condition
is false.

Syntax
if (condition1) {
// block of code to be executed if condition1 is true
} else if (condition2) {
// block of code to be executed if the condition1 is false and
condition2 is true
} else {
// block of code to be executed if the condition1 is false and
condition2 is false
}

Example
int time = 22;
if (time < 10) {
cout << "Good morning.";
} else if (time < 20) {
cout << "Good day.";
} else {
cout << "Good evening.";
}
// Outputs "Good evening."

Short Hand If...Else (Ternary


Operator)
There is also a short-hand if else, which is known as the ternary
operator because it consists of three operands. It can be used to replace
multiple lines of code with a single line. It is often used to replace simple if
else statements:

Syntax
variable = (condition) ? expressionTrue : expressionFalse;

C++ Switch Statements


Use the switch statement to select one of many code blocks to be executed.

Syntax
switch(expression) {
case x:
// code block
break;
case y:
// code block
break;
default:
// code block
}

This is how it works:

 The switch expression is evaluated once


 The value of the expression is compared with the values of each case
 If there is a match, the associated block of code is executed
 The break and default keywords are optional, and will be described
later in this chapter

The example below uses the weekday number to calculate the weekday
name:

Example
int day = 4;
switch (day) {
case 1:
cout << "Monday";
break;
case 2:
cout << "Tuesday";
break;
case 3:
cout << "Wednesday";
break;
case 4:
cout << "Thursday";
break;
case 5:
cout << "Friday";
break;
case 6:
cout << "Saturday";
break;
case 7:
cout << "Sunday";
break;
}
// Outputs "Thursday" (day 4)

C++ For Loop


When you know exactly how many times you want to loop through a block of
code, use the for loop instead of a while loop:
Syntax
for (statement 1; statement 2; statement 3) {
// code block to be executed
}

Statement 1 is executed (one time) before the execution of the code block.

Statement 2 defines the condition for executing the code block.

Statement 3 is executed (every time) after the code block has been
executed.

The example below will print the numbers 0 to 4:

Example
for (int i = 0; i < 5; i++) {
cout << i << "\n";
}

C++ While Loop


The while loop loops through a block of code as long as a specified condition
is true:

Syntax
while (condition) {
// code block to be executed
}

In the example below, the code in the loop will run, over and over again, as
long as a variable (i) is less than 5:

Example
int i = 0;
while (i < 5) {
cout << i << "\n";
i++;
}
The Do/While Loop
The do/while loop is a variant of the while loop. This loop will execute the
code block once, before checking if the condition is true, then it will repeat
the loop as long as the condition is true.

Syntax
do {
// code block to be executed
}
while (condition);

The example below uses a do/while loop. The loop will always be executed at
least once, even if the condition is false, because the code block is executed
before the condition is tested:

Example
int i = 0;
do {
cout << i << "\n";
i++;
}
while (i < 5);

C++ Break
You have already seen the break statement used in an earlier chapter of this
tutorial. It was used to "jump out" of a switch statement.

The break statement can also be used to jump out of a loop.

This example jumps out of the loop when i is equal to 4:

Example
for (int i = 0; i < 10; i++) {
if (i == 4) {
break;
}
cout << i << "\n";
}

C++ Continue
The continue statement breaks one iteration (in the loop), if a specified
condition occurs, and continues with the next iteration in the loop.

This example skips the value of 4:

Example
for (int i = 0; i < 10; i++) {
if (i == 4) {
continue;
}
cout << i << "\n";
}
Break and Continue in While
Loop
You can also use break and continue in while loops:

Break Example
int i = 0;
while (i < 10) {
cout << i << "\n";
i++;
if (i == 4) {
break;
}
}

Continue Example
int i = 0;
while (i < 10) {
if (i == 4) {
i++;
continue;
}
cout << i << "\n";
i++;
}

Arrays
An array is a series of elements of the same type placed in contiguous memory locations that
can be individually referenced by adding an index to a unique identifier.

For example, an array containing 5 integer values of type int called foo could be represented
as:

Arrays are used to store multiple values in a single variable, instead of


declaring separate variables for each value.
To declare an array, define the variable type, specify the name of the array
followed by square brackets and specify the number of elements it should
store:

string cars[4];

Change an Array Element


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

cars[0] = "Opel";

Example
string cars[4] = {"Volvo", "BMW", "Ford", "Mazda"};
cars[0] = "Opel";
cout << cars[0];
// Now outputs Opel instead of Volvo

We have now declared a variable that holds an array of four strings. To insert
values to it, we can use an array literal - place the values in a comma-
separated list, inside curly braces:

string cars[4] = {"Volvo", "BMW", "Ford", "Mazda"};

To create an array of three integers, you could write:

int myNum[3] = {10, 20, 30};

C++ Multi-dimensional Arrays


C++ allows multidimensional arrays. Here is the general form of a
multidimensional array declaration −
type name[size1][size2]...[sizeN];
For example, the following declaration creates a three dimensional 5 . 10 .
4 integer array −
int threedim[5][10][4];
Two-Dimensional Arrays
The simplest form of the multidimensional array is the two-dimensional
array. A two-dimensional array is, in essence, a list of one-dimensional
arrays. To declare a two-dimensional integer array of size x,y, you would
write something as follows −
type arrayName [ x ][ y ];
Where type can be any valid C++ data type and arrayName will be a
valid C++ identifier.
A two-dimensional array can be think as a table, which will have x number
of rows and y number of columns. A 2-dimensional array a, which contains
three rows and four columns can be shown as below −

Thus, every element in array a is identified by an element name of the


form a[ i ][ j ], where a is the name of the array, and i and j are the
subscripts that uniquely identify each element in a.

Initializing Two-Dimensional Arrays


Multidimensioned arrays may be initialized by specifying bracketed values
for each row. Following is an array with 3 rows and each row have 4
columns.
int a[3][4] = {
{0, 1, 2, 3} , /* initializers for row indexed by 0 */
{4, 5, 6, 7} , /* initializers for row indexed by 1 */
{8, 9, 10, 11} /* initializers for row indexed by 2 */
};
The nested braces, which indicate the intended row, are optional. The
following initialization is equivalent to previous example −
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
Accessing Two-Dimensional Array Elements
An element in 2-dimensional array is accessed by using the subscripts,
i.e., row index and column index of the array. For example −
int val = a[2][3];
The above statement will take 4 th element from the 3rd row of the array.
You can verify it in the above digram.
#include <iostream>
using namespace std;

int main () {
// an array with 5 rows and 2 columns.
int a[5][2] = { {0,0},
{1,2},
{2,4},
{3,6},
{4,8}};

// output each array element's value


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

cout << "a[" << i << "][" << j << "]: ";
cout << a[i][j]<< endl;
}
}
return 0;
}

C++ Pointer to an Array ??

C++ Structures
Structures (also called structs) are a way to group several related variables
into one place. Each variable in the structure is known as a member of the
structure.

Unlike an array, a structure can contain many different data types (int, string,
bool, etc.).

Create a Structure
To create a structure, use the struct keyword and declare each of its
members inside curly braces.

After the declaration, specify the name of the structure variable


(myStructure in the example below):
struct { // Structure declaration
int myNum; // Member (int variable)
string myString; // Member (string variable)
} a; // Structure variable

Access Structure Members


To access members of a structure, use the dot syntax ( .):

Example
Assign data to members of a structure and print it:

// Create a structure variable called myStructure


struct {
int myNum;
string myString;
} myStructure;

// Assign values to members of myStructure


myStructure.myNum = 1;
myStructure.myString = "Hello World!";

// Print members of myStructure


cout << myStructure.myNum << "\n";
cout << myStructure.myString << "\n";

One Structure in Multiple


Variables
You can use a comma (,) to use one structure in many variables:

struct {
int myNum;
string myString;
} myStruct1, myStruct2, myStruct3; // Multiple structure
variables separated with commas

This example shows how to use a structure in two different variables:


Example
Use one structure to represent two cars:

struct {
string brand;
string model;
int year;
} myCar1, myCar2; // We can add variables by separating them with
a comma here

// Put data into the first structure


myCar1.brand = "BMW";
myCar1.model = "X5";
myCar1.year = 1999;

// Put data into the second structure


myCar2.brand = "Ford";
myCar2.model = "Mustang";
myCar2.year = 1969;

// Print the structure members


cout << myCar1.brand << " " << myCar1.model << " " <<
myCar1.year << "\n";
cout << myCar2.brand << " " << myCar2.model << " " <<
myCar2.year << "\n";

Named Structures
By giving a name to the structure, you can treat it as a data type. This means
that you can create variables with this structure anywhere in the program at
any time.

To create a named structure, put the name of the structure right after
the struct keyword:

struct myDataType { // This structure is named "myDataType"


int myNum;
string myString;
};

To declare a variable that uses the structure, use the name of the structure
as the data type of the variable:

myDataType myVar;
Example
Use one structure to represent two cars:

// Declare a structure named "car"


struct car {
string brand;
string model;
int year;
};

int main() {
// Create a car structure and store it in myCar1;
car myCar1;
myCar1.brand = "BMW";
myCar1.model = "X5";
myCar1.year = 1999;

// Create another car structure and store it in myCar2;


car myCar2;
myCar2.brand = "Ford";
myCar2.model = "Mustang";
myCar2.year = 1969;

// Print the structure members


cout << myCar1.brand << " " << myCar1.model << " " <<
myCar1.year << "\n";
cout << myCar2.brand << " " << myCar2.model << " " <<
myCar2.year << "\n";

return 0;
}

Pointer in C++
A pointer can be used to store the memory address of other
variables, functions, or even other pointers. The use of pointers
allows low-level memory access, dynamic memory allocation, and
many other functionality in C++.
int a = 4 ;
int b = 5, c = 6, d = 10;
int * pNum = NULL;
pNum = &a;
or
int *pNum = &a;
cout << &a << " " << pNum << " " << *pNum << endl;

Types of Pointers in C++


Double Pointers

we can define a pointer that stores the memory address of another


pointer. Such pointers are called double-pointers or pointers-to-
pointer. Instead of pointing to a data value, they point to another
pointer.
int main ()
{
int a = 4 ;
int b = 5, c = 6, d = 10;
int * pNum = NULL;
pNum = &a;

int **pVar = NULL;


pVar = &pNum ;

cout << &a << " " << pNum << " " << *pNum << endl;
cout << pNum << " " << pVar << endl ;
return 0;

NULL Pointer

The Null Pointers are those pointers that do not point to any
memory location. They can be created by assigning a NULL value to
the pointer. A pointer of any type can be assigned the NULL value.
int * pNum = NULL;
Void Pointer
The Void pointers in C are the pointers of type void. It means that
they do not have any associated data type. They are also
called generic pointers as they can point to any type and can be
typecasted to any type.
Syntax
void * pointer_name;
int data = 15;
void * Variable = &data;

One of the main properties of void pointers is that they cannot be


dereferenced.

Wild Pointers
The Wild Pointers are pointers that have not been initialized with
something yet. These types of C-pointers can cause problems in
our programs and can eventually cause them to crash.
Example

int *ptr;
char *str;

Constant Pointers

In constant pointers, the memory address stored inside the pointer


is constant and cannot be modified once it is defined. It will always
point to the same memory address.

Int const * pVar ;

Pointer to Constant

The pointers pointing to a constant value that cannot be modified


are called pointers to a constant. Here we can only access the data
pointed by the pointer, but cannot modify it. Although, we can
change the address stored in the pointer to constant.

const int * pVar;


 Dangling pointer: A pointer pointing to a memory
location that has been deleted (or freed) is called a
dangling pointer.

#include <iostream>;

using namespace std;

int main()
{
int myVar ;
int *myPointer;

myVar = 8;
myPointer = &myVar;

cout << "delete-ing pointers " << endl;


cout << "Memory address: " << myPointer << endl;

// Seems I can't *just* delete it, as it triggers an error


delete myPointer;
cout << "myPointer: " << myPointer << endl;
// Error: a.out(14399) malloc: *** error for object 0x7fff61e537f4:
// pointer being freed was not allocated
// *** set a breakpoint in malloc_error_break to debug
// Abort trap: 6

// Using the new keyword befor deleting it works, but


// does it really frees up the space?
myPointer = new int;
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// myPointer continues to store a memory address.

// Using NULL before deleting it, seems to work.


myPointer = NULL;
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// myPointer returns 0.

1. Why won't the first case work? Seems the most straightforward use
to use and delete a pointer? The error says the memory wasn't
allocated but 'cout' returned an address.
2. On the second example the error is not being triggered but doing a
cout of the value of myPointer still returns a memory address?
3. Does #3 really work? Seems to work to me, the pointer is no longer
storing an address, is this the proper way to delete a pointer?

myVar = 8; //not dynamically allocated. Can't call delete on it.


myPointer = new int; //dynamically allocated, can call delete on it.
The first variable was allocated on the stack. You can call delete only on
memory you allocated dynamically (on the heap) using the new operator.
3.
myPointer = NULL;
delete myPointer;
The above did nothing at all. You didn't free anything, as the pointer
pointed at NULL.

The following shouldn't be done:


myPointer = new int;
myPointer = NULL; //leaked memory, no pointer to above int
delete myPointer; //no point at all
You pointed it at NULL, leaving behind leaked memory (the new int you
allocated). You should free the memory you were pointing at. There is no way
to access that allocated new int anymore, hence memory leak.

The correct way:


myPointer = new int;
delete myPointer; //freed memory
myPointer = NULL; //pointed dangling ptr to NULL

Creating References
A reference variable is a "reference" to an existing variable, and it is created
with the & operator:

string food = "Pizza"; // food variable


string &meal = food; // reference to food

Now, we can use either the variable name food or the reference name meal to
refer to the food variable:

Example
string food = "Pizza";
string &meal = food;

cout << food << "\n"; // Outputs Pizza


cout << meal << "\n"; // Outputs Pizza

References Pointers

The variable cannot The variable can be


be reassigned in reassigned in
Reassignment Reference. Pointers.
References Pointers

It shares the same Pointers have their


address as the own memory
Memory Address original variable. address.

It is storing the
It is referring to
address of the
another variable.
Work variable.

It does not have null It can have value


Null Value value. assigned as null.

This variable is The pointer does it


referenced by the work by the method
method pass by known as pass by
Arguments value. reference.

When to use What


The performances are exactly the same as references are
implemented internally as pointers. But still, you can keep some
points in your mind to decide when to use what:
 Use references:

 In function parameters and return types.


 Use pointers:

 If pointer arithmetic or passing a NULL pointer is


needed. For example, for arrays (Note that
accessing an array is implemented using pointer
arithmetic).
 To implement data structures like a linked list, a
tree, etc. and their algorithms. This is so because,
in order to point to different cells, we have to use
the concept of pointers.

C++ Functions
A function is a group of statements that together perform a task. Every C++
program has at least one function, which is main(), and all the most trivial
programs can define additional functions.

// declaring functions prototypes


#include <iostream>
using namespace std;

void odd (int x);


void even (int x);

int main()
{
int i;
do {
cout << "Please, enter number (0 to exit): ";
cin >> i;
odd (i);
} while (i!=0);
return 0;
}

void odd (int x)


{
if ((x%2)!=0) cout << "It is odd.\n";
else even (x);
}

void even (int x)


{
if ((x%2)==0) cout << "It is even.\n";
else odd (x);
}

#include <iostream>
using namespace std;

int swap_number(int &num1, int &num2, int &num3);


int swap_number(int &num1, int &num2, int &num3)
{
num3 = num1;
num1 = num2;
num2 = num3;
//cout << num1 << " " << num2 << endl;
return 0;
}
int main()
{
int a= 10, b=20, c=0;
swap_number(a,b, c);

cout << a << " " << b << " " << c << endl;
return 0;

Function Overloading
With function overloading, multiple functions can have the same name
with different parameters:

Example
int myFunction(int x)
float myFunction(float x)
double myFunction(double x, double y)

Consider the following example, which have two functions that add numbers
of different type:

Example
int plusFuncInt(int x, int y) {
return x + y;
}

double plusFuncInt(double x, double y) {


return x + y;
}

int main()
{
int myNum1 = plusFuncInt (8, 5);
double myNum2 = plusFuncInt (4.3, 6.26);
cout << "Int: " << myNum1 << "\n";
cout << "Double: " << myNum2;
return 0;
}
Pass By Reference
In the examples from the previous page, we used normal variables when we
passed parameters to a function. You can also pass a reference to the
function. This can be useful when you need to change the value of the
arguments:

Example
void swapNums(int &x, int &y) {
int z = x;
x = y;
y = z;
}

int main() {
int firstNum = 10;
int secondNum = 20;

cout << "Before swap: " << "\n";


cout << firstNum << secondNum << "\n";

// Call the function, which will change the values of firstNum


and secondNum
swapNums(firstNum, secondNum);

cout << "After swap: " << "\n";


cout << firstNum << secondNum << "\n";

return 0;
}

Recursion
Recursion is the technique of making a function call itself. This technique
provides a way to break complicated problems down into simple problems
which are easier to solve.

Recursion may be a bit difficult to understand. The best way to figure out how
it works is to experiment with it.
Recursion Example
Adding two numbers together is easy to do, but adding a range of numbers is
more complicated. In the following example, recursion is used to add a range
of numbers together by breaking it down into the simple task of adding two
numbers:

// factorial calculator
#include <iostream>
using namespace std;

long factorial (long a)


{
if (a > 1)
return (a * factorial (a-1));
else
return 1;
}

int main ()
{
long number = 9;
cout << number << "! = " << factorial (number);
return 0;
}

C++ What is OOPs?


OOP stands for Object-Oriented Programming.

Procedural programming is about writing procedures or functions that


perform operations on the data, while object-oriented programming is about
creating objects that contain both data and functions.

Object-oriented programming has several advantages over procedural


programming:

 OOP is faster and easier to execute


 OOP provides a clear structure for the programs
 OOP helps to keep the C++ code DRY "Don't Repeat Yourself", and
makes the code easier to maintain, modify and debug
 OOP makes it possible to create full reusable applications with less
code and shorter development time

Tip: The "Don't Repeat Yourself" (DRY) principle is about reducing the
repetition of code. You should extract out the codes that are common for the
application, and place them at a single place and reuse them instead of
repeating it.

C++ What are Classes and


Objects?
Classes and objects are the two main aspects of object-oriented
programming.

Look at the following illustration to see the difference between class and
objects:

class
Fruit

objects
Apple

Banana

Mango

Another example:

class
Car

objects
Volvo

Audi
Toyota

So, a class is a template for objects, and an object is an instance of a class.

When the individual objects are created, they inherit all the variables and
functions from the class.

You will learn much more about classes and objects in the next chapter.

C++ Classes/Objects
C++ is an object-oriented programming language.

Everything in C++ is associated with classes and objects, along with its
attributes and methods. For example: in real life, a VolvoCar is an object.
The car has attributes, such as weight and color, and methods, such as
drive and brake.

Attributes and methods are basically variables and functions that belongs
to the class. These are often referred to as "class members".

A class is a user-defined data type that we can use in our program, and it
works as an object constructor, or a "blueprint" for creating objects.

Create a Class
To create a class, use the class keyword:

Example
Create a class called "MyClass":

class MyClass { // The class


public: // Access specifier
int myNum; // Attribute (int variable)
string myString; // Attribute (string variable)
};

Example explained
 The class keyword is used to create a class called MyClass.
 The public keyword is an access specifier, which specifies that
members (attributes and methods) of the class are accessible from
outside the class. You will learn more about access specifiers later.
 Inside the class, there is an integer variable myNum and a string
variable myString. When variables are declared within a class, they
are called attributes.
 At last, end the class definition with a semicolon ;.

Create an Object
In C++, an object is created from a class. We have already created the class
named MyClass, so now we can use this to create objects.

To create an object of MyClass, specify the class name, followed by the object
name.

To access the class attributes (myNum and myString), use the dot syntax (.) on
the object:

Example
Create an object called "myObj" and access the attributes:

class MyClass { // The class


public: // Access specifier
int myNum; // Attribute (int variable)
string myString; // Attribute (string variable)
};

int main() {
MyClass `; // Create an object of MyClass

// Access attributes and set values


myObj.myNum = 15;
myObj.myString = "Some text";

// Print attribute values


cout << myObj.myNum << "\n";
cout << myObj.myString;
return 0;
}
Multiple Objects
You can create multiple objects of one class:

Example
// Create a Car class with some attributes
class Car {
public:
string brand;
string model;
int year;
};

int main() {
// Create an object of Car
Car carObj1;
carObj1.brand = "BMW";
carObj1.model = "X5";
carObj1.year = 1999;

// Create another object of Car


Car carObj2;
carObj2.brand = "Ford";
carObj2.model = "Mustang";
carObj2.year = 1969;

// Print attribute values


cout << carObj1.brand << " " << carObj1.model << " " <<
carObj1.year << "\n";
cout << carObj2.brand << " " << carObj2.model << " " <<
carObj2.year << "\n";
return 0;
}

#include <iostream>
using namespace std;

class MyClass
{
public:

int data;
string Myname;
double dVal;
};

int main ()
{
MyClass TestObj ;
MyClass* TstObj = new MyClass; // Dynamically object creation

TestObj.data = 200;
TstObj->dVal = 10.10;

cout << TestObj.data << " " << TstObj->dVal << endl;
delete TstObj ;
TstObj = NULL;
return 0;
}

Class Methods
Methods are functions that belongs to the class.

There are two ways to define functions that belongs to a class:

 Inside class definition


 Outside class definition

In the following example, we define a function inside the class, and we name
it "myMethod".

Note: You access methods just like you access attributes; by creating an
object of the class and using the dot syntax ( .):

Inside Example
class MyClass
{ // The class
public: // Access specifier
void myMethod() { // Method/function defined inside the
class
cout << "Hello World!";
}
};

int main()
{
MyClass myObj; // Create an object of MyClass
myObj.myMethod(); // Call the method
return 0;
}
To define a function outside the class definition, you have to declare it inside
the class and then define it outside of the class. This is done by specifying the
name of the class, followed the scope resolution :: operator, followed by the
name of the function:

Outside Example
class MyClass
{ // The class
public: // Access specifier
void myMethod(); // Method/function declaration
};

// Method/function definition outside the class


void MyClass::myMethod()
{
cout << "Hello World!";
}

int main() {
MyClass myObj; // Create an object of MyClass
myObj.myMethod(); // Call the method
return 0;
}

Parameters
You can also add parameters:

Example
#include <iostream>
using namespace std;

class Car
{
public:
int speed(int maxSpeed);
};

int Car::speed(int maxSpeed)


{
return maxSpeed;
}
int main()
{
Car myObj; // Create an object of Car
cout << myObj.speed(200); // Call the method with an argument
return 0;
}

Access Specifiers
In C++, there are three access specifiers:

 public - members are accessible from outside the class


 private - members cannot be accessed (or viewed) from outside the
class
 protected - members cannot be accessed from outside the class,
however, they can be accessed in inherited classes. You will learn more
about Inheritance later.

Access Private Members


To access a private attribute, use public "get" and "set" methods:

Example
#include <iostream>
using namespace std;

class Employee {
private:
// Private attribute
int salary;

public:
// Setter
void setSalary(int s)
{
salary = s;
}
// Getter
int getSalary()
{
return salary;
}
};
int main() {
Employee myObj;
myObj.setSalary(50000);
cout << myObj.getSalary();
return 0;
}

Encapsulation
The meaning of Encapsulation, is to make sure that "sensitive" data is
hidden from users. To achieve this, you must declare class
variables/attributes as private (cannot be accessed from outside the class). If
you want others to read or modify the value of a private member, you can
provide public get and set methods.

Why Encapsulation?
 It is considered good practice to declare your class attributes as private
(as often as you can). Encapsulation ensures better control of your
data, because you (or others) can change one part of the code without
affecting other parts
 Increased security of data

C++ Inheritance
The capability of a class to derive properties and characteristics from another
class is called Inheritance. Inheritance is one of the most important features
of Object-Oriented Programming.
Inheritance is a feature or a process in which, new classes are created from
the existing classes. The new class created is called “derived class” or “child
class” and the existing class is known as the “base class” or “parent class”.
The derived class now is said to be inherited from the base class.
Why and when to use inheritance?
Consider a group of vehicles. You need to create classes for Bus, Car, and
Truck. The methods fuelAmount(), capacity(), applyBrakes() will be the
same for all three classes. If we create these classes avoiding inheritance
then we have to write all of these functions in each of the three classes as
shown below figure:
You can clearly see that the above process results in duplication of the
same code 3 times. This increases the chances of error and data
redundancy. To avoid this type of situation, inheritance is used. If we create
a class Vehicle and write these three functions in it and inherit the rest of
the classes from the vehicle class, then we can simply avoid the duplication
of data and increase re-usability. Look at the below diagram in which the
three classes are inherited from vehicle class:

Using inheritance, we have to write the functions only one time instead of
three times as we have inherited the rest of the three classes from the base
class (Vehicle).
Implementing inheritance in C++: For creating a sub-class that is
inherited from the base class we have to follow the below syntax.
Derived Classes: A Derived class is defined as the class derived from the
base class.
Syntax

#include <iostream>

using namespace std;

// Base class
class Shape {
public:
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}

protected:
int width;
int height;
};

// Derived class
class Rectangle: public Shape {
public:
int getArea() {
return (width * height);
}
};

int main(void) {
Rectangle Rect;

Rect.setWidth(5);
Rect.setHeight(7);

// Print the area of the object.


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

return 0;
}

Access Control and Inheritance


A derived class can access all the non-private members of its base class.
Thus base-class members that should not be accessible to the member
functions of derived classes should be declared private in the base class.
We can summarize the different access types according to - who can
access them in the following way –

Access public protected private

Same class yes yes yes

Derived classes yes yes no

Outside classes yes no no


protected -
// Base class
class Employee {
protected: // Protected access specifier
int salary;
};

// Derived class
class Programmer: public Employee {
public:
int bonus;
void setSalary(int s) {
salary = s;
}
int getSalary() {
return salary;
}
};

int main() {
Programmer myObj;
myObj.setSalary(50000);
myObj.bonus = 15000;
cout << "Salary: " << myObj.getSalary() << "\n";
cout << "Bonus: " << myObj.bonus << "\n";
return 0;
}

What is Constructor in C++?

A constructor in C++ is a special ‘MEMBER FUNCTION’ having the same name as that of
its class which is used to initialize some valid values to the data members of an object

A class constructor is a special member function of a class that is


executed whenever we create new objects of that class.
A constructor will have exact same name as the class and it does not have
any return type at all, not even void. Constructors can be very useful for
setting initial values for certain member variables.
Following example explains the concept of constructor –
#include <iostream>
using namespace std;

class Line {
public:
void setLength( double len );
double getLength( void );
Line(); // This is the constructor
private:
double length;
};

// Member functions definitions including constructor


Line::Line(void) {
cout << "Object is being created" << endl;
}
void Line::setLength( double len ) {
length = len;
}
double Line::getLength( void ) {
return length;
}

// Main function for the program


int main() {
Line line;

// set line length


line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;

return 0;
}
When the above code is compiled and executed, it produces the following
result −
Object is being created
Length of line : 6

Parameterized Constructor
A default constructor does not have any parameter, but if you need, a
constructor can have parameters. This helps you to assign initial value to
an object at the time of its creation as shown in the following example −
#include <iostream>

using namespace std;


class Line {
public:
void setLength( double len );
double getLength( void );
Line(double len); // This is the constructor

private:
double length;
};

// Member functions definitions including constructor


Line::Line( double len)
{
cout << "Object is being created, length = " << len << endl;
length = len;
}
void Line::setLength( double len ) {
length = len;
}
double Line::getLength( void ) {
return length;
}

// Main function for the program


int main() {
Line line(10.0);

// get initially set length.


cout << "Length of line : " << line.getLength() <<endl;

// set line length again


line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;

return 0;
}
When the above code is compiled and executed, it produces the following
result −
Object is being created, length = 10
Length of line : 10
Length of line : 6

The Class Destructor


A destructor is a special member function of a class that is executed
whenever an object of it's class goes out of scope or whenever the delete
expression is applied to a pointer to the object of that class.
A destructor will have exact same name as the class prefixed with a tilde
(~) and it can neither return a value nor can it take any parameters.
Destructor can be very useful for releasing resources before coming out of
the program like closing files, releasing memories etc.
Following example explains the concept of destructor −
#include <iostream>

using namespace std;


class Line {
public:
void setLength( double len );
double getLength( void );
Line(); // This is the constructor declaration
~Line(); // This is the destructor: declaration

private:
double length;
};

// Member functions definitions including constructor


Line::Line(void) {
cout << "Object is being created" << endl;
}
Line::~Line(void) {
cout << "Object is being deleted" << endl;
}
void Line::setLength( double len ) {
length = len;
}
double Line::getLength( void ) {
return length;
}

// Main function for the program


int main() {
Line line;

// set line length


line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;

return 0;
}
When the above code is compiled and executed, it produces the following
result −
Object is being created
Length of line : 6
Object is being deleted

C++ Overloading (Function )


If we create two or more members having the same name but different in
number or type of parameter, it is known as C++ overloading. In C++, we
can overload:

1. #include <iostream>
2. using namespace std;
3. class Cal {
4. public:
5. static int add(int a,int b){
6. return a + b;
7. }
8. static int add(int a, int b, int c)
9. {
10. return a + b + c;
11. }
12. };
13. int main(void) {
14. Cal C; // class object decl
aration.
15. cout<<C.add(10, 20)<<endl;
16. cout<<C.add(12, 20, 23);
17. return 0;
18. }

1. #include<iostream>
2. using namespace std;
3. void fun(int);
4. void fun(int,int);
5. void fun(int i)
6. {
7. std::cout << "Value of i is : " <<i<< std::endl;
8. }
9. void fun(int a,int b=9)
10. {
11. std::cout << "Value of a is : " <<a<< std::endl;
12. std::cout << "Value of b is : " <<b<< std::endl;
13. }
14. int main()
15. {
16. fun(12);
17.
18. return 0;
19. }

The above example shows an error "call of overloaded 'fun(int)' is


ambiguous". The fun(int a, int b=9) can be called in two ways: first is by
calling the function with one argument, i.e., fun(12) and another way is
calling the function with two arguments, i.e., fun(4,5). The fun(int i)
function is invoked with one argument. Therefore, the compiler could not
be able to select among fun(int i) and fun(int a,int b=9).

o Function with pass by reference

Let's see a simple example.

1. #include <iostream>
2. using namespace std;
3. void fun(int);
4. void fun(int &);
5. int main()
6. {
7. int a=10;
8. fun(a); // error, which f()?
9. return 0;
10.}
11. void fun(int x)
12.{
13. std::cout << "Value of x is : " <<x<< std::endl;
14.}
15. void fun(int &b)
16.{
17. std::cout << "Value of b is : " <<b<< std::endl;
18.}
The above example shows an error "call of overloaded 'fun(int&)' is
ambiguous". The first function takes one integer argument and the
second function takes a reference parameter as an argument. In this case,
the compiler does not know which function is needed by the user as there
is no syntactical difference between the fun(int) and fun(int &).

Pass by value vs. pass by


reference

Pass by value

Pass by value means that a copy of the actual parameter’s value


is made in memory, i.e. the caller and callee have two
independent variables with the same value. If the callee modifies
the parameter value, the effect is not visible to the caller.

Overview:

1. Passes an argument by value.


2. Callee does not have any access to the underlying element
in the calling code.
3. A copy of the data is sent to the callee.
4. Changes made to the passed variable do not affect the
actual value.
Pass by reference

Pass by reference (also called pass by address) means to pass


the reference of an argument in the calling function to the
corresponding formal parameter of the called function so that a
copy of the address of the actual parameter is made in memory,
i.e. the caller and the callee use the same variable for the
parameter. If the callee modifies the parameter variable, the
effect is visible to the caller’s variable.

Overview:

1. Passes an argument by reference.


2. Callee gives a direct reference to the programming element
in the calling code.
3. The memory address of the stored data is passed.
4. Changes to the value have an effect on the original data.
When to use pass by value?

If we are building multi-threaded application, then we don’t


have to worry of objects getting modified by other threads. In
distributed application pass by value can save the over network
overhead to keep the objects in sync.

When to use pass by reference?

In pass by reference, no new copy of the variable is made,


so overhead of copying is saved. This makes programs
efficient especially when passing objects of large structs or
classes.

void incrementCount(int count)//pass by value


{
count=count+1;//increments the value of count inside the function
}
int main()
{
int count=0;// initialze the variable count
int result=0;// initialze the variable result
incrementCount(count);//call increment function
cout<<"Pass by value\n";
cout<<"Count:";
cout<<count;//prints the value of count after the function call
return 0;
}
void incrementCount(int & count)//& to pass by reference
{
count=count+1;//increments the value of count
}
int main()
{
int count=0;//initialize the variable count
int result=0;// initialize the variable result
incrementCount(count);//increment value of count
cout<<"Pass by Reference\n";
cout<<"Count:";
cout<<count;//prints count after the function call
return 0;
}

Copy Constructor in C++


A copy constructor is a member function that initializes an object using
another object of the same class. In simple terms, a constructor which
creates an object by initializing it with an object of the same class, which has
been created previously is known as a copy constructor.

Types of Copy Constructors

1. Default Copy Constructor

An implicitly defined copy constructor will copy the bases and members of an
object in the same order that a constructor would initialize the bases and
members of the object.
// Implicit copy constructor Calling
#include <iostream>
using namespace std;

class Sample
{
int id;

public:
void init(int x) { id = x; }
void display() { cout << endl << "ID=" << id; }
};

int main()
{
Sample obj1;
obj1.init(10);
obj1.display();

// Implicit Copy Constructor Calling


Sample obj2(obj1); // or obj2=obj1;
obj2.display();
return 0;
}

2. User Defined Copy Constructor

A user-defined copy constructor is generally needed when an object owns


pointers or non-shareable references, such as to a file, in which case a
destructor and an assignment operator should also be written

 C++
// Explicitly copy constructor Calling

#include<iostream>

using namespace std;

class Sample

int id;

public:

void init(int x)

id=x;

Sample(){} //default constructor with empty body

Sample(Sample &t) //copy constructor

{
id=t.id;

void display()

cout<<endl<<"ID="<<id;

};

int main()

Sample obj1;

obj1.init(10);

obj1.display();

Sample obj2(obj1); //or obj2=obj1; copy constructor called

obj2.display();

return 0;

When is the copy constructor called?


In C++, a Copy Constructor may be called in the following cases:
 When an object of the class is returned by value.
 When an object of the class is passed (to a function) by value as an
argument.
 When an object is constructed based on another object of the same
class.
 When the compiler generates a temporary object.
It is, however, not guaranteed that a copy constructor will be called in all
these cases, because the C++ Standard allows the compiler to optimize the
copy away in certain cases, one example is the return value
optimization (sometimes referred to as RVO).

When is a user-defined copy constructor needed?


If we don’t define our own copy constructor, the C++ compiler creates a
default copy constructor for each class which does a member-wise copy
between objects. The compiler-created copy constructor works fine in
general. We need to define our own copy constructor only if an object has
pointers or any runtime allocation of the resource like a file handle, a
network connection, etc.

The default constructor does only shallow copy.

Deep copy is possible only with a user-defined copy constructor. In a


user-defined copy constructor, we make sure that pointers (or references) of
copied objects point to new memory locations.
Example – Class Where a Copy Constructor is Required
Following is a complete C++ program to demonstrate the use of the Copy
constructor. In the following String class, we must write a copy constructor.
Example:
 C++
// C++ program to demonstrate the

// Working of Copy constructor

#include <cstring>

#include <iostream>

using namespace std;

class String {

private:

char* s;

int size;

public:

String(const char* str = NULL); // constructor

~String() { delete[] s; } // destructor

String(const String&); // copy constructor

void print()

cout << s << endl;

} // Function to print string

void change(const char*); // Function to change

};

// In this the pointer returns the CHAR ARRAY

// in the same sequence of string object but

// with an additional null pointer '\0'

String::String(const char* str)


{

size = strlen(str);

s = new char[size + 1];

strcpy(s, str);

void String::change(const char* str)

delete[] s;

size = strlen(str);

s = new char[size + 1];

strcpy(s, str);

String::String(const String& old_str)

size = old_str.size;

s = new char[size + 1];

strcpy(s, old_str.s);

int main()

String str1("GeeksQuiz");

String str2 = str1;

str1.print(); // what is printed ?

str2.print();

str2.change("GeeksforGeeks");
str1.print(); // what is printed now ?

str2.print();

return 0;

Output
GeeksQuiz
GeeksQuiz
GeeksQuiz
GeeksforGeeks

What would be the problem if we remove the copy constructor from the
above code?

If we remove the copy constructor from the above program, we don’t get the
expected output. The changes made to str2 reflect in str1 as well which is
never expected.

 C++
#include<iostream>

#include<cstring>

using namespace std;

class String

private:

char *s;

int size;

public:

String(const char *str = NULL); // constructor

~String() { delete [] s; }// destructor


void print() { cout << s << endl; }

void change(const char *); // Function to change

};

String::String(const char *str)

size = strlen(str);

s = new char[size+1];

strcpy(s, str);

// In this the pointer returns the CHAR ARRAY

// in the same sequence of string object but

// with an additional null pointer '\0'

void String::change(const char *str)

delete [] s;

size = strlen(str);

s = new char[size+1];

strcpy(s, str);

int main()

String str1("GeeksQuiz");

String str2 = str1;

str1.print(); // what is printed ?

str2.print();
str2.change("GeeksforGeeks");

str1.print(); // what is printed now ?

str2.print();

return 0;

Can we make the copy constructor private?


Yes, a copy constructor can be made private. When we make a copy
constructor private in a class, objects of that class become non-copyable.
This is particularly useful when our class has pointers or dynamically
allocated resources. In such situations, we can either write our own copy
constructor like the above String example or make a private copy constructor
so that users get compiler errors rather than surprises at runtime.

Why argument to a copy constructor must be passed as a reference?


A copy constructor is called when an object is passed by value. Copy
constructor itself is a function. So if we pass an argument by value in a copy
constructor, a call to the copy constructor would be made to call the copy
constructor which becomes a non-terminating chain of calls. Therefore
compiler doesn’t allow parameters to be passed by value.
Why argument to a copy constructor should be const?
One reason for passing const reference is, that we should use const in C++
wherever possible so that objects are not accidentally modified. This is one
good reason for passing reference as const,

C++ Polymorphism
The word “polymorphism” means having many forms. In simple words, we
can define polymorphism as the ability of a message to be displayed in more
than one form.
A real-life example of polymorphism is a person who at the same time can
have different characteristics. A man at the same time is a father, a husband,
and an employee. So the same person exhibits different behavior in different
situations. This is called polymorphism.
Operator Overloading

C++ has the ability to provide the operators with a special meaning for a data
type, this ability is known as operator overloading. For example, we can
make use of the addition operator (+) for string class to concatenate two
strings. We know that the task of this operator is to add two operands. So a
single operator ‘+’, when placed between integer operands, adds them and
when placed between string operands, concatenates them.

#include <iostream>
using namespace std;

class Complex {
private:
int real, imag;

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

// This is automatically called


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

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

// An example call to "operator+"


Complex c3 = c1 + c2;
c3.print();
}

Output
12 + i9

2. Runtime Polymorphism
This type of polymorphism is achieved by Function Overriding. Late binding
and dynamic polymorphism are other names for runtime polymorphism. The
function call is resolved at runtime in runtime polymorphism . In contrast, with
compile time polymorphism, the compiler determines which function call to
bind to the object after deducing it at runtime.
A. Function Overriding

Function Overriding occurs when a derived class has a definition for one of
the member functions of the base class. That base function is said to be
overridden.

//base.h file
#pragma once
class PolymorphismClass
{
public:
PolymorphismClass(void);
~PolymorphismClass(void);

virtual int sum (int a, int b) ; // pure virtual


function
int sub (int a, int b);
private:
int salary();
};

//base.cpp File
#include "PolymorphismClass.h"
#include "ChildPolyClass.h"
#include "ChildChildClass.h"

PolymorphismClass::PolymorphismClass(void)
{
}

PolymorphismClass::~PolymorphismClass(void)
{
}

int PolymorphismClass::sum (int a, int b)


{
int c = a + b;
return c;
}

int PolymorphismClass::sub (int a, int b)


{
int c = a - b;
return c;
}
int main ()
{
PolymorphismClass* BaseObj;
ChildPolyClass ChildObj;
BaseObj = &ChildObj;

BaseObj->sub(50,20);
BaseObj->sum(100,50); // it recognise which function
has to call at RUN time
BaseObj->PolymorphismClass::sum(564,584);

ChildObj.sub(10,5);
ChildObj.sum(1,2);

/*ChildPolyClass *ChildObj;
ChildChildClass ChildChildObj;
ChildObj = &ChildChildObj;
ChildObj.sub(55,11);*/
return 0;
}
//child class.h
#pragma once
#include "polymorphismclass.h"

class ChildPolyClass :
public PolymorphismClass
{
public:
ChildPolyClass(void);
~ChildPolyClass(void);

int sum (int a, int b);


virtual int sub (int a, int b);
};

//child class.cpp
#include "ChildPolyClass.h"

ChildPolyClass::ChildPolyClass(void)
{
}

ChildPolyClass::~ChildPolyClass(void)
{
}

int ChildPolyClass::sum (int a, int b)


{
int c = a + b + 200;
return c;
}

int ChildPolyClass::sub (int a, int b)


{
int c = a - b - 1;
return c;
}
// base.h
#pragma once

class OverrideBaseClass
{
public:
OverrideBaseClass(void);
~OverrideBaseClass(void);

virtual int Sum (int num1, int num2);


int Display();
virtual int raisedSalary(int curentSalry);

};
// base.cpp
#include "OverrideBaseClass.h"

OverrideBaseClass::OverrideBaseClass(void)
{
}

OverrideBaseClass::~OverrideBaseClass(void)
{
}

int OverrideBaseClass::Sum (int num1, int num2)


{
int c = num1 + num2 ;
return c;
}

int OverrideBaseClass::raisedSalary(int curentSalry)


{
int NewSalary = curentSalry;
return NewSalary
}

// child.h
#pragma once
#include "overridebaseclass.h"

class OverrideChildClass : public OverrideBaseClass


{
public:
OverrideChildClass(void);
~OverrideChildClass(void);

int Sum (int num1, int num2);


int sub(int a, int b);
};

// child.cpp
#include "OverrideChildClass.h"

OverrideChildClass::OverrideChildClass(void)
{
}

OverrideChildClass::~OverrideChildClass(void)
{
}

int OverrideChildClass::Sum (int num1, int num2)


{
int c = num1 + num2 + 200 ;
return c;
}

int OverrideChildClass::sub (int a, int b)


{
int c = a - b ;
return c;
}

//main.cpp
#include <iostream>
#include "OverrideBaseClass.h"
#include "OverrideChildClass.h"

using namespace std;

int main ()
{
OverrideBaseClass *objBase = new OverrideBaseClass();
objBase->Sum(10, 20); // IT WILL BASE CLASS FUNCTION

OverrideChildClass objChild;
// IF SAME FUNCTION AVAILABLE IN BASE AND CHILD AND IF WE WANT TO
CALL BASE SAME CLASS
// FUNCTION THEN WE HAVE TO BASE CLASS SCOP
objChild.OverrideBaseClass::Sum(20,30);
objChild.Sum(4,5); // IT WILL CALL CHILD CLASS FUNCTION

objBase = &objChild;
objBase->Sum(10,200); // IT WILL CHILD CLASS FUNCTION

objBase->OverrideBaseClass::Sum(100,10); // IT WILL BASE CLASS


FUNCTION

return 0;
}
//Base Class
#pragma once
class BaseClass
{
public:
BaseClass(void);
~BaseClass(void);

int Sum(int a, int b);


};

#include <iostream>
#include "BaseClass.h"
#include "ChildClass.h"
using namespace std;

BaseClass::BaseClass(void)
{
}
BaseClass::~BaseClass(void)
{
}
int BaseClass::Sum(int a, int b)
{
int c = a + b;
return c;
}

// Child Class
#pragma once
#include "BaseClass.h"

class ChildClass : public BaseClass


{
public:
ChildClass(void);
~ChildClass(void);

int Sum(int a, int b);

};
#include "ChildClass.h"
ChildClass::ChildClass(void)
{
}
ChildClass::~ChildClass(void)
{
}
int ChildClass::Sum(int a, int b)
{
int c = a + b + 5;
return c;
}

// Main Class
#include "BaseClass.h"
#include "ChildClass.h"
#include <iostream>

using namespace std;


int main()
{
BaseClass* pBaseObj = new BaseClass();
pBaseObj->Sum(2, 4); // it will call base class function

// Function Overriding
ChildClass* pChildObj = new ChildClass();
pChildObj->Sum(5, 4); // it will call child class function
pChildObj->BaseClass::Sum(20,10); // it will call base class function,
//doesnt matter even we have not define same virtual function inside the base
class

ChildClass pObjChild;
pBaseObj = &pObjChild; // we are assigning address of child class to the base
class
pBaseObj->Sum(50,10); // it will call child class function if same virtual function
available inside the base.
// otherwise it will call base class function to the base class onject.
return 0;
}

Compile time polymorphism Run time polymorphism

The function to be invoked is known at the compile The function to be invoked is known at the run
time. time.

It is also known as overloading, early binding and It is also known as overriding, Dynamic
static binding. binding and late binding.

Overloading is a compile time polymorphism where Overriding is a run time polymorphism where
more than one method is having the same name more than one method is having the same
but with the different number of parameters or the name, number of parameters and the type of
type of the parameters. the parameters.

It is achieved by function overloading and operator It is achieved by virtual functions and


overloading. pointers.

It provides fast execution as it is known at the It provides slow execution as it is known at


compile time. the run time.

It is less flexible as mainly all the things execute at It is more flexible as all the things execute at
the compile time. the run time.

Differences b/w compile time and run time


polymorphism.

Virtual Function
Virtual functions in C++ are used to achieve runtime
polymorphism. This means that the function that is called at
runtime depends on the type of the object that is being used. This
is useful for implementing methods that behave differently
depending on the type of object that they are called on.

#include <iostream>
using namespace std;.
class Base
{
public:
virtual void show_val()
{
cout << "Class::Base";
}
};
class Derived:public Base
{
public:
void show_val()
{
cout << "Class::Derived"; }
};
int main() {
Base* b; //Base class pointer
Derived d; //Derived class object
b = &d;
b->show_val(); //late Binding
}
Class::Derived

// base.h
#pragma once

class EmployeeClass
{
public:
EmployeeClass(void);
~EmployeeClass(void);

virtual int RaisedSalary (int currentSal);


};

// base.cpp
#include "EmployeeClass.h"

EmployeeClass::EmployeeClass(void)
{
}

EmployeeClass::~EmployeeClass(void)
{
}

int EmployeeClass::RaisedSalary (int currentSal)


{
int NewSalary = currentSal;
return NewSalary;
}

.
.
.
#include <iostream>
#include "EmployeeClass.h"
#include "EngineerClass.h"
#include "ManagerClass.h"
using namespace std;

int main ()
{
EmployeeClass *pBaseClass = new EmployeeClass();
pBaseClass->RaisedSalary(2000); // call base class function with baseclass pointer

ManagerClass objManager;
pBaseClass = &objManager;
pBaseClass->RaisedSalary(200000);// call child class function with baseclass point

EmployeeClass *pNewBaseClass = new EmployeeClass();


EngineerClass objEngineer;
pNewBaseClass = &objEngineer;
pNewBaseClass->RaisedSalary(100000);// call child class function with baseclass po

return 0;
}

What is the use?


Virtual functions allow us to create a list of base class pointers and
call methods of any of the derived classes without even knowing
the kind of derived class object.

Real-Life Example to Understand the Implementation of Virtual


Function

Consider employee management software for an organization.


Let the code has a simple base class Employee, the class contains
virtual functions like raiseSalary(), transfer(), promote(), etc.
Different types of employees like Managers, Engineers, etc., may
have their own implementations of the virtual functions present in
base class Employee.
In our complete software, we just need to pass a list of employees
everywhere and call appropriate functions without even knowing
the type of employee. For example, we can easily raise the salary
of all employees by iterating through the list of employees. Every
type of employee may have its own logic in its class, but we don’t
need to worry about them because if raiseSalary() is present for a
specific employee type, only that function would be called.

How does the compiler perform runtime resolution?

The compiler maintains two things to serve this purpose:


 vtable: A table of function pointers, maintained per class.
 vptr: A pointer to vtable, maintained per object instance
(see this for an example).

A virtual destructor is a destructor that is declared virtual in a


class. When an object of a derived class is deleted using a pointer
to the base class, the virtual destructor of the base class is called
first, followed by the virtual destructor of the derived class. This
ensures that the destructor for the most specific class is always
called, regardless of the type of pointer used to delete the object.
Here is an example of a virtual destructor in C++:
class Base {
public:
virtual ~Base() { std::cout << "Base destructor called\n"; }
};

class Derived : public Base {


public:
~Derived() { std::cout << "Derived destructor called\n"; }
};

int main() {
Base *base = new Derived();
delete base;
}
Derived destructor called
Base destructor called
Virtual destructors are useful in situations where you need to
ensure that the resources allocated by a derived class are
properly cleaned up even if the object is deleted using a pointer
to the base class.

What is pure virtual function?


A pure virtual function is a virtual function that has no definition within the class. Let's
understand the concept of pure virtual function through an example.
A pure virtual function (or abstract function) in C++ is a virtual function for which we can
have an implementation, But we must override that function in the derived class, otherwise,
the derived class will also become an abstract class. A pure virtual function is declared by
assigning 0 in the declaration.

Characteristics of a pure virtual function.

o A pure virtual function is a "do nothing" function. Here "do nothing"


means that it just provides the template, and derived class
implements the function.
o It can be considered as an empty function means that the pure
virtual function does not have any definition relative to the base
class.
o Programmers need to redefine the pure virtual function in the
derived class as it has no definition in the base class.
o A class having pure virtual function cannot be used to create direct
objects of its own. It means that the class is containing any pure
virtual function then we cannot create the object of that class. This
type of class is known as an abstract class.

// C++ program to demonstrate that


// an abstract class can have constructors.

#include <iostream>
using namespace std;

// An abstract class with constructor


class Base
{
protected:
// protected member variable
int x;

public:
// pure virtual function
virtual void fun() = 0;

// constructor of Base class


Base(int i)
{
x = i;
cout << "Constructor of base called\n";
}
};

class Derived : public Base


{
// private member variable
int y;

public:
// calling the constructor of Base class
Derived(int i, int j)
: Base(i)
{
y = j;
}
// implementation of pure virtual function
void fun()
{
cout << "x = " << x << ", y = " << y << '\n';
}
};
int main(void)
{
// creating an object of Derived class
Derived d(4, 5);

// calling the fun() function of Derived class


d.fun();

// creating an object of Derived class using


// a pointer of the Base class
Base* ptr = new Derived(6, 7);

// calling the fun() function using the


// pointer
ptr->fun();

return 0;
}

1. #include <iostream>
2. using namespace std;
3. // Abstract class
4. class Shape
5. {
6. public:
7. virtual float calculateArea() = 0; // pure virtual function.
8. };
9. class Square : public Shape
10. {
11. float a;
12. public:
13. Square(float l)
14. {
15. a = l;
16. }
17. float calculateArea()
18. {
19. return a*a;
20. }
21. };
22. class Circle : public Shape
23. {
24. float r;
25. public:
26.
27. Circle(float x)
28. {
29. r = x;
30. }
31. float calculateArea()
32. {
33. return 3.14*r*r ;
34. }
35. };
36. class Rectangle : public Shape
37. {
38. float l;
39. float b;
40. public:
41. Rectangle(float x, float y)
42. {
43. l=x;
44. b=y;
45. }
46. float calculateArea()
47. {
48. return l*b;
49. }
50. };
51. int main()
52. {
53.
54. Shape *shape;
55. Square s(3.4);
56. Rectangle r(5,6);
57. Circle c(7.8);
58. shape =&s;
59. int a1 =shape->calculateArea();
60. shape = &r;
61. int a2 = shape->calculateArea();
62. shape = &c;
63. int a3 = shape->calculateArea();
64. std::cout << "Area of the square is " <<a1<< std::endl;
65. std::cout << "Area of the rectangle is " <<a2<< std::endl;
66. std::cout << "Area of the circle is " <<a3<< std::endl;
67. return 0;
68. }

Virtual function Pure virtual function

A virtual function is a member A pure virtual function is a member


function in a base class that can function in a base class whose
be redefined in a derived class. declaration is provided in a base class
and implemented in a derived class.

The classes which are containing The classes which are containing pure
virtual functions are not abstract virtual function are the abstract classes.
classes.

In case of a virtual function, In case of a pure virtual function,


definition of a function is provided definition of a function is not provided
in the base class. in the base class.

The base class that contains a The base class that contains a pure
virtual function can be virtual function becomes an abstract
instantiated. class, and that cannot be instantiated.

If the derived class will not If the derived class does not define the
redefine the virtual function of the pure virtual function; it will not throw
base class, then there will be no any error but the derived class
effect on the compilation. becomes an abstract class.

All the derived classes may or may All the derived classes must define the
not redefine the virtual function. pure virtual function.

‘this’ pointer
The compiler supplies an implicit pointer along with the names of the functions as ‘this’.
The ‘this’ pointer is passed as a hidden argument to all nonstatic member function calls
and is available as a local variable within the body of all nonstatic functions. ‘this’ pointer
is not available in static member functions as static member functions can be called
without any object

#include<iostream>
using namespace std;

/* local variable is same as a member's name */


class Test
{
private:
int x;
public:
void setX (int x)
{
// The 'this' pointer is used to retrieve the object's x
// hidden by the local variable 'x'
this->x = x;
}
void print() { cout << "x = " << x << endl; }
};

int main()
{
Test obj;
int x = 20;
obj.setX(x);
obj.print();
return 0;
}
Output:
x = 20
For constructors, initializer list can also be used when parameter name is same as member’s name.

2) To return reference to the calling object

/* Reference to the calling object can be returned */


Test& Test::func ()
{
// Some processing
return *this;
}
When a reference to a local object is returned, the returned reference can be used to chain function
calls on a single object.

#include<iostream>
using namespace std;

class Test
{
private:
int x;
int y;
public:
Test(int x = 0, int y = 0) { this->x = x; this->y = y; }
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};

int main()
{
Test obj1(5, 5);

// Chained function calls. All calls modify the same object


// as the same object is returned by reference
obj1.setX(10).setY(20);

obj1.print();
return 0;
}

Output:
x = 10 y = 20

Stack vs Heap Memory Allocation


Stack Allocation: The allocation happens on contiguous blocks of
memory. We call it a stack memory allocation because the allocation
happens in the function call stack. The size of memory to be allocated is
known to the compiler and whenever a function is called, its variables
get memory allocated on the stack. And whenever the function call is
over, the memory for the variables is de-allocated. This all happens using
some predefined routines in the compiler. A programmer does not have
to worry about memory allocation and de-allocation of stack variables.
This kind of memory allocation is also known as Temporary memory
allocation because as soon as the method finishes its execution all the
data belonging to that method flushes out from the stack automatically.
This means any value stored in the stack memory scheme is accessible as
long as the method hasn’t completed its execution and is currently in a
running state.
Key Points:
 It’s a temporary memory allocation scheme where the data
members are accessible only if the method( ) that contained them
is currently running.
 It allocates or de-allocates the memory automatically as soon as
the corresponding method completes its execution.
 We receive the corresponding error Java.
lang. StackOverFlowError by JVM, If the stack memory is filled
completely.
 Stack memory allocation is considered safer as compared to heap
memory allocation because the data stored can only be accessed
by the owner thread.
 Memory allocation and de-allocation are faster as compared to
Heap-memory allocation.
 Stack memory has less storage space as compared to Heap-
memory.
 C++

int main()
{
// All these variables get memory
// allocated on stack
int a;
int b[10];
int n = 20;
int c[n];
}

Heap Allocation: The memory is allocated during the execution of


instructions written by programmers. It is called a heap because it is a
pile of memory space available to programmers to allocate and de-
allocate. Every time when we made an object it always creates in Heap-
space and the referencing information to these objects is always stored
in Stack-memory. Heap memory allocation isn’t as safe as Stack memory
allocation because the data stored in this space is accessible or visible to
all threads. If a programmer does not handle this memory well,
a memory leak can happen in the program.
The Heap-memory allocation is further divided into three
categories:- These three categories help us to prioritize the
data(Objects) to be stored in the Heap-memory or in the Garbage
collection.
Young Generation – It’s the portion of the memory where all the

new data(objects) are made to allocate the space and whenever
this memory is completely filled then the rest of the data is stored
in Garbage collection.
 Old or Tenured Generation – This is the part of Heap-memory
that contains the older data objects that are not in frequent use or
not in use at all are placed.
 Permanent Generation – This is the portion of Heap-memory that
contains the JVM’s metadata for the runtime classes and
application methods.
Key Points:
 We receive the corresponding error message if Heap-space is
entirely full, java. lang.OutOfMemoryError by JVM.
 This memory allocation scheme is different from the Stack-space allocation, here no
automatic de-allocation feature is provided. We need to use a Garbage collector to
remove the old unused objects in order to use the memory efficiently.
 The processing time(Accessing time) of this memory is quite slow as compared to
Stack-memory.
 Heap memory is also not as threaded-safe as Stack-memory because data stored in
Heap-memory are visible to all threads.
 The size of the Heap-memory is quite larger as compared to the Stack-memory.
 Heap memory is accessible or exists as long as the whole application(or java
program) runs.
 CPP
int main()
{
// This memory for 10 integers
// is allocated on heap.
int *ptr = new int[10];
}

In order to pinpoint each memory location in a program’s memory, we


assign each byte of memory an “address”. The addresses go from 0 all
the way to the largest possible address, depending on the machine. As
the figure below, the text, data, and heap segments have low address
numbers, while the stack memory has higher addresses.

Memory layout of a c++


program
By convention, we express these addresses in base 16 numbers. For
instance, the smallest possible address is 0x00000000 (where the 0x means
base 16), and the largest possible address could be 0xFFFFFFFF.

Stack
As shown above, the stack segment is near the top of memory with high
address. Every time a function is called, the machine allocates some stack
memory for it. When a new local variables is declared, more stack
memory is allocated for that function to store the variable. Such
allocations make the stack grow downwards. After the function returns,
the stack memory of this function is deallocated, which means all local
variables become invalid. The allocation and deallocation for stack
memory is automatically done. The variables allocated on the stack
are called stack variables, or automatic variables.
The following figures show examples of what stack memory looks like
when the corresponding code is run:

From <https://courses.engr.illinois.edu/cs225/fa2022/resources/stack-heap/>
Since the stack memory of a function gets deallocated after the function
returns, there is no guarantee that the value stored in those area will stay
the same. A common mistake is to return a pointer to a stack
variable in a helper function. After the caller gets this pointer, the
invalid stack memory can be overwritten at anytime. The following figures
demonstrate one example of such scenario. Assume there is a Cube class
that has methods getVolume and getSurfaceArea, as well as a private
variable width.
These examples provide a simplified version of stack memory. In reality, a
function’s stack stores more than just local variables. You can find out
more about what exactly is in the stack by taking a computer architecture
class. In addition, the above example could cause a segmentation fault
when we are calling c->getVolume() or c->getSurfaceArea(). This is because if
the value of c is invalid, then the machine can’t find the getVolume function
associated with c. If this happens, this program will crash instead of
producing incorrect values.

Heap
In the previous section we saw that functions cannot return pointers of
stack variables. To solve this issue, you can either return by copy, or put
the value at somewhere more permanent than stack memory. Heap
memory is such a place. Unlike stack memory, heap memory is
allocated explicitly by programmers and it won’t be deallocated
until it is explicitly freed. To allocate heap memory in C++, use the
keyword new followed by the constructor of what you want to allocate. The
return value of new operator will be the address of what you just created
(which points to somewhere in the heap).
The figures below demonstrate what happens in both stack and heap
when the corresponding code is executed:
You may notice in the above example that even at the end of the
program, the heap memory is still not freed. This is called a memory leak.

Memory leaks in small programs might not look like a big deal, but for
long-running servers, memory leaks can slow down the whole machine
and eventually cause the program to crash.

To free heap memory, use the key word delete followed by the pointer to
the heap memory. Be careful about the memory you freed. If you try to
use the pointers to those memory after you free them, it will
cause undefined behavior. To avoid such issues, it is good practice to
set the value of freed pointers to nullptr immediately after delete. Here is
an example that correctly frees memory after using it.
In the figures above, you can see that heap memory are not allocated continuously from bottom to
top. This is because unlike stack where the invalid memory is always at the bottom, the user can free
heap memory that’s in between valid memories, causing fragmentations in the heap. In order to
reuse memory efficiently, there are numerous heap allocation scheme that try to pick the “best”
spot for you. You will learn more about memory allocation in a system programming class.

File Handling through C++ Classes

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.

Classes for File stream operations :-

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.
/* 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;
}

Linked List Data Structure


A linked list is a fundamental data structure in computer science.
It consists of nodes where each node contains data and
a reference (link) to the next node in the sequence. This allows
for dynamic memory allocation and
efficient insertion and deletion operations compared to arrays.

Linked Lists vs Arrays

Linked List:
 Data Structure: Non-contiguous
 Memory Allocation: Dynamic
 Insertion/Deletion: Efficient
 Access: Sequential
Array:
 Data Structure: Contiguous
 Memory Allocation: Static
 Insertion/Deletion: Inefficient
 Access: Random

C++ Vectors
In C++, vectors are used to store elements of similar data types. However,
unlike arrays, the size of a vector can grow dynamically.
That is, we can change the size of the vector during the execution of a
program as per our requirements.

Vectors are part of the C++ Standard Template Library. To use vectors, we
need to include the vector header file in our program.

#include <vector>

C++ Vector Declaration


Once we include the header file, here's how we can declare a vector in C+
+:

std::vector<T> vector_name;

The type parameter <T> specifies the type of the vector. It can be any
primitive data type such as int , char , float , etc. For example,
vector<int> num;

Here, num is the name of the vector.


Notice that we have not specified the size of the vector during the
declaration. This is because the size of a vector can grow dynamically, so it
is not necessary to define it.

C++ Vector Initialization


There are different ways to initialize a vector in C++.

Method 1:

// Initializer list
vector<int> vector1 = {1, 2, 3, 4, 5};
// Uniform initialization
vector<int> vector2 {1, 2, 3, 4, 5};

Here, we are initializing the vector by providing values directly to the vector.
Now, both vector1 and vector2 are initialized with values 1, 2, 3, 4, 5.
Method 2:

vector<int> vector3(5, 12);

Here, 5 is the size of the vector and 12 is the value.


This code creates an int vector with size 5 and initializes the vector with
the value of 12. So, the vector is equivalent to

vector<int> vector3 = {12, 12, 12, 12, 12};

Example: C++ Vector Initialization


#include <iostream>
#include <vector>
using namespace std;

int main() {
// initializer list
vector<int> vector1 = {1, 2, 3, 4, 5};
// uniform initialization
vector<int> vector2{6, 7, 8, 9, 10};
// method 3
vector<int> vector3(5, 12);
cout << "vector1 = ";
// ranged loop
for (const int& i : vector1) {
cout << i << " ";
}
cout << "\nvector2 = ";
// ranged loop
for (const int& i : vector2) {
cout << i << " ";
}
cout << "\nvector3 = ";
// ranged loop
for (int i : vector3) {
cout << i << " ";
}
return 0;
}

Output

vector1 = 1 2 3 4 5
vector2 = 6 7 8 9 10
vector3 = 12 12 12 12 12

Here, we have declared and initialized three different vectors using three
different initialization methods and displayed their contents.

Basic Vector Operations


The vector class provides various methods to perform different operations
on vectors. We will look at some commonly used vector operations in this
tutorial:
 Add elements

 Access elements

 Change elements

 Remove elements

1. Add Elements to a Vector


To add a single element into a vector, we use the push_back() function. It
inserts an element into the end of the vector. For example,

#include <iostream>
#include <vector>
using namespace std;

int main() {
vector<int> num {1, 2, 3, 4, 5};

cout << "Initial Vector: ";

for (const int& i : num) {


cout << i << " ";
}
// add the integers 6 and 7 to the vector
num.push_back(6);
num.push_back(7);

cout << "\nUpdated Vector: ";

for (const int& i : num) {


cout << i << " ";
}

return 0;
}

Output

Initial Vector: 1 2 3 4 5
Updated Vector: 1 2 3 4 5 6 7

Here, we have initialized an int vector num with the elements {1, 2, 3, 4,

5} . Notice the statements

num.push_back(6);
num.push_back(7);

Here, the push_back() function adds elements 6 and 7 to the vector.

Note: We can also use the insert() and emplace() functions to add
elements to a vector.

2. Access Elements of a Vector


In C++, we use the index number to access the vector elements. Here, we
use the at() function to access the element from the specified index. For
example,
#include <iostream>
#include <vector>
using namespace std;

int main() {
vector<int> num {1, 2, 3, 4, 5};

cout << "Element at Index 0: " << num.at(0) << endl;


cout << "Element at Index 2: " << num.at(2) << endl;
cout << "Element at Index 4: " << num.at(4);

return 0;
}
Run Code

Output

Element at Index 0: 1
Element at Index 2: 3
Element at Index 4: 5

Here,

 num.at(0) - access element at index 0


 num.at(2) - access element at index 2
 num.at(4) - access element at index 4
Note: Like an array, we can also use the square brackets [] to access
vector elements. For example,

vector<int> num {1, 2, 3};


cout << num[1]; // Output: 2

However, the at() function is preferred over [] because at() throws an


exception whenever the vector is out of bound, while [] gives a garbage
value.

vector<int> num {1, 2, 3};

// gives garbage value


cout << num[4];

// throws an exception
cout << num.at(4);
3. Change Vector Element
We can change an element of the vector using the same at() function. For
example,
#include <iostream>
#include <vector>
using namespace std;

int main() {
vector<int> num {1, 2, 3, 4, 5};

cout << "Initial Vector: ";

for (const int& i : num) {


cout << i << " ";
}

// change elements at indexes 1 and 4


num.at(1) = 9;
num.at(4) = 7;

cout << "\nUpdated Vector: ";

for (const int& i : num) {


cout << i << " ";
}

return 0;
}
Run Code

Output

Initial Vector: 1 2 3 4 5
Updated Vector: 1 9 3 4 7

In the above example, notice the statements,

num.at(1) = 9;
num.at(4) = 7;

Here, we have assigned new values to indexes 1 and 4. So the value


at index 1 is changed to 9 and the value at index 4 is changed to 7.

4. Delete Elements from C++ Vectors


To delete a single element from a vector, we use the pop_back() function.
For example,
#include <iostream>
#include <vector>

using namespace std;

int main() {
vector<int> prime_numbers{2, 3, 5, 7};

// initial vector
cout << "Initial Vector: ";
for (int i : prime_numbers) {
cout << i << " ";
}

// remove the last element


prime_numbers.pop_back();

// final vector
cout << "\nUpdated Vector: ";
for (int i : prime_numbers) {
cout << i << " ";
}

return 0;
}
Run Code

Output
Initial Vector: 2 3 5 7
Updated Vector: 2 3 5

In the above example, notice the statement,

prime_numbers.pop_back();

Here, we have removed the last element (7) from the vector.

C++ Vector Functions


In C++, the vector header file provides various functions that can be used
to perform different operations on a vector.

Function Description

size() returns the number of elements present in the vector

clear() removes all the elements of the vector

front() returns the first element of the vector

back() returns the last element of the vector

empty() returns 1 (true) if the vector is empty

capacity() check the overall size of a vector


C++ Vector Iterators
Vector iterators are used to point to the memory address of a vector
element. In some ways, they act like pointers in C++.
We can create vector iterators with the syntax

vector<T>::iterator iteratorName;

For example, if we have 2 vectors of int and double types, then we will
need 2 different iterators corresponding to their types:

// iterator for int vector


vector<int>::iterator iter1;

// iterator for double vector


vector<double>::iterator iter2;

Initialize Vector Iterators


We can initialize vector iterators using the begin() and end() functions.
1. begin() function
The begin() function returns an iterator that points to the first element of
the vector. For example,

vector<int> num = {1, 2, 3};


vector<int>::iterator iter;

// iter points to num[0]


iter = num.begin();

2. end() function
The end() function points to the theoretical element that comes after the
final element of the vector. For example,
// iter points to the last element of num
iter = num.end() - 1;

Here, due to the nature of the end() function, we have used the
code num.end() - 1 to point to the last element of the num vector i.e. num[2] .

Example: C++ Vector Iterators


#include <iostream>
#include <vector>
using namespace std;

int main() {
vector<int> num {1, 2, 3, 4, 5};

// declare iterator
vector<int>::iterator iter;

// initialize the iterator with the first element


iter = num.begin();

// print the vector element


cout << "num[0] = " << *iter << endl;

// iterator points to the 3rd element


iter = num.begin() + 2;
cout << "num[2] = " << *iter;

// iterator points to the last element


iter = num.end() - 1;
cout << "num[4] = " << *iter;

return 0;
}
Run Code

Output
num[0] = 1
num[2] = 3
num[4] = 5

In this program, we have declared an int vector iterator iter to use it with
the vector num .

// declare iterator
vector<int>::iterator iter;

Then, we initialized the iterator to the first element of the vector using
the begin() function.

// initialize the iterator with the first element


iter = num.begin();

Then, we printed the vector element by dereferencing the iterator:

// print the vector element


cout << "num[0] = " << *iter << endl;

Then, we printed the 3rd element of the vector by changing the value
of iter to num.begin() + 2 .

Finally, we printed the last element of the vector using the end() function.

Example: Iterate Through Vector Using Iterators


#include <iostream>
#include <vector>
using namespace std;

int main() {
vector<int> num {1, 2, 3, 4, 5};

// declare iterator
vector<int>::iterator iter;
// use iterator with for loop
for (iter = num.begin(); iter != num.end(); ++iter) {
cout << *iter << " ";
}

return 0;
}
Run Code

Output

1 2 3 4 5

Here, we have used a for loop to initialize and iterate the iterator iter from
the beginning of the vector to the end of the vector using
the begin() and end() functions.

// use iterator with for loop


for (iter = num.begin(); iter != num.end(); ++iter) {
cout << *iter << " ";
}

try and catch blocks are fundamental components of exception handling, a mechanism
used to manage runtime errors and exceptional conditions gracefully.

try block:
 A try block encloses a section of code where exceptions might occur during
program execution.
 If an exception is thrown within the try block, the execution of the current
function terminates immediately, and control is transferred to a
matching catch block.
catch block:
 A catch block follows a try block and is designed to handle specific types of
exceptions.
 When an exception is thrown in the try block, the C++ runtime searches for
a catch block whose parameter type matches the type of the thrown
exception.
 If a match is found, the code within that catch block is executed, allowing for
error recovery or appropriate handling of the exceptional condition.
 Multiple catch blocks can be associated with a single try block to handle
different types of exceptions. A general catch-all block catch(...) can be
used as the last handler to catch any unhandled exceptions.
throw keyword:
 The throw keyword is used to explicitly raise an exception.
 It can be used within a try block or a function called from a try block.
 The operand of throw specifies the type of exception being thrown, which can
be a standard exception class (e.g., std::runtime_error, std::bad_alloc) or
a custom exception class.
Example:
C++
#include <iostream>
#include <stdexcept> // For std::runtime_error

int divide(int numerator, int denominator) {


if (denominator == 0) {
throw std::runtime_error("Division by zero is not allowed.");
}
return numerator / denominator;
}

int main() {
try {
int result = divide(10, 0); // This will throw an exception
std::cout << "Result: " << result << std::endl;
} catch (const std::runtime_error& e) {
std::cerr << "Error: " << e.what() << std::endl;
} catch (...) { // Catch-all for any other unexpected exceptions
std::cerr << "An unknown error occurred." << std::endl;
}
return 0;
}

You might also like