Unit 4
Unit 4
C++ Basics:
Overview
Program structure
namespace
identifiers
variables
constants
enum
operators
typecasting
control structures
Object-Oriented Programming
C++ fully supports object-oriented programming, including the four pillars of object-oriented development
• Encapsulation
• Data hiding
• Inheritance
• Polymorphism
C++ is a general-purpose programming language that was developed as an enhancement of the C language
to include object-oriented paradigm. It is an imperative and a compiled language.
C++ is a middle-level language rendering it the advantage of programming low-level (drivers, kernels) and
even higher-level applications (games, GUI, desktop apps etc.). The basic syntax and code structure of both
C and C++ are the same.
Some of the features & key-points to note about the programming language are as follows:
• Simple: It is a simple language in the sense that programs can be broken down into logical units and
parts, has a rich library support and a variety of data-types.
• Rich library support: Has a rich library support (Both standard ~ built-in data structures, algorithms
etc.) as well 3rd party libraries (e.g. Boost libraries) for fast and rapid development.
• Speed of execution: C++ programs excel in execution speed. Since, it is a compiled language, and
also hugely procedural. Newer languages have extra in-built default features such as garbage-
collection, dynamic typing etc. which slow the execution of the program overall. Since there is no
additional processing overhead like this in C++, it is blazing fast.
• Pointer and direct Memory-Access: C++ provides pointer support which aids users to directly
manipulate storage address. This helps in doing low-level programming (where one might need to have
explicit control on the storage of variables).
• Object-Oriented: One of the strongest points of the language which sets it apart from C. Object-
Oriented support helps C++ to make maintainable and extensible programs. I.e. Large-scale
applications can be built. Procedural code becomes difficult to maintain as code-size grows.
Standard Libraries:
The ANSI standard is an attempt to ensure that C++ is portable; that code you write for Microsoft's
compiler will compile without errors, using a compiler on a Mac, UNIX, a Windows box, or an Alpha.
The ANSI standard has been stable for a while, and all the major C++ compiler manufacturers support the
ANSI standard.
Learning C++
The most important thing while learning C++ is to focus on concepts.
The purpose of learning a programming language is to become a better programmer; that is, to become
more effective at designing and implementing new systems and at maintaining old ones.
C++ supports a variety of programming styles. You can write in the style of Fortran, C, Smalltalk, etc., in
any language. Each style can achieve its aims effectively while maintaining runtime and space efficiency.
Use of C++
Here are some awesome facts about C++ that may interest you:
1. The name of C++ signifies the evolutionary nature of the changes from C. “++” is the C increment
operator.
2. C++ is one of the predominant languages for the development of all kind of technical and commercial
software.
3. C++ introduces Object-Oriented Programming, not present in C. Like other things, C++ supports the
four primary features of OOP: encapsulation, polymorphism, abstraction, and inheritance.
4. C++ got the OOP features from Simula67 Programming language.
5. A function is a minimum requirement for a C++ program to run.(at least main() function)
As we know some basic features of an object oriented programming language are the Inheritance,
Encapsulation, and Polymorphism. Any language that supports these features completely are known as
object oriented programming languages. Some languages like C++ supports these three but not fully, so they
are partially object oriented language. Let us see the reason why C++ is not known as completely object
oriented language.
• In C++, we need the main() function to start executing, but in C++, the main functions are not
present inside the class. So we can also write code without using class in C++. Some OOP languages
like JAVA, it needs one class same as file name, the main function is present inside that.
• In C++, we can use the global variables. That can be accessed from anywhere. It does not complete
privacy to the data, as no one can be restricted to access and modify those data, so it ensures
encapsulations partially. In JAVA, we can use variables in class, and also use the access specifier on
them.
• C++ has the concept of friend functions. Using friend functions, we can access private and protected
members of one class. It also violets the concept of OOL. Java does not support friend functions in it.
What is C++?
C++ gives programmers a high level of control over system resources and memory.
The language was updated 3 major times in 2011, 2014, and 2017 to C++11, C++14, and
C++17.
C++ can be found in today's operating systems, Graphical User Interfaces, and embedded
systems.
C++ is portable and can be used to develop applications that can be adapted to multiple
platforms.
As C++ is close to C# and Java, it makes it easy for programmers to switch to C++ or vice
versa
Get Started:
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.
We will use Code::Blocks in our tutorial, which we believe is a good place to start.
#include <iostream.h>
int main()
Header files are included at the beginning just like in C program. Here iostream is a header
file which provides us with input & output streams. Header files contained predeclared
function libraries, which can be used by users for their ease.
Using namespace std, tells the compiler to use standard namespace. Namespace collects
identifiers used for class, object and variables. Namespace can be used by two ways in a
program, either by the use of using statement at the beginning, like we did in above
mentioned program or by using name of namespace as prefix before the identifier with scope
resolution (::) operator.
Example: std::cout << "A";
main(), is the function which holds the executing part of program its return type is int.
cout <<, is used to print anything on screen, same as printf in C language. cin and cout are
same as scanf and printf, only difference is that you do not need to mention format specifiers
like, %d for int etc, in cout & cin.
Comments in C++ Program:
For single line comments, use // before mentioning comment, like
/*this is
a multiple line
comment */
class Abc
int main()
obj.display(); //
This is how a class is defined, once a class is defined, then its object is created and the
member functions are used.
Variables can be declared anywhere in the entire program, but must be declared, before they
are used. Hence, we don't need to declare variable at the start of the program.
Compile and Execute C++ Program
Let's look at how to save the file, compile and run the program. Please follow the steps given
below −
• Open a text editor and add the code as above.
• Save the file as: hello.cpp
• Open a command prompt and go to the directory where you saved the file.
• Type 'g++ hello.cpp' and press enter to compile your code. If there are no errors in your
code the command prompt will take you to the next line and would generate a.out
executable file.
• Now, type 'a.out' to run your program.
• You will be able to see ' Hello World ' printed on the window.
➢ Namespace
➢ Identifiers
➢ Variables,
➢ Constants
➢ Enum,
➢ Operators
➢ Typecasting control structures
Namespace:
Consider a situation, when we have two persons with the same name, Zara, in the same class. Whenever we
need to differentiate them definitely we would have to use some additional information along with their
name, like either the area, if they live in different area or their mother’s or father’s name, etc.
Same situation can arise in your C++ applications. For example, you might be writing some code that has a
function called xyz() and there is another library available which is also having same function xyz(). Now
the compiler has no way of knowing which version of xyz() function you are referring to within your code.
A namespace is designed to overcome this difficulty and is used as additional information to differentiate
similar functions, classes, variables etc. with the same name available in different libraries. Using
namespace, you can define the context in which names are defined. In essence, a namespace defines a
scope.
Consider following C++ program.
Output:
Compiler Error:
'value' has a previous declaration as 'int value'
In each scope, a name can only represent one entity. So, there cannot be two variables with the same name in
the same scope. Using namespaces, we can create two variables or member functions having the same name.
// Here we can see that more than one variables
#include <iostream>
namespace first
// Global variable
int main()
// Local variable
// operator ::
return 0;
Output:
500
C++ Identifiers:
All C++ variables must be identified with unique names.
Identifiers can be short names (like x and y) or more descriptive names (age, sum, totalVolume).
Example
// Good
int minutesPerHour = 60;
The general rules for constructing names for variables (unique identifiers) are:
When you do not want others (or yourself) to override existing variable values, use
the const keyword (this will declare the variable as "constant", which
means unchangeable and read-only):
Constants
Constants are expressions with a fixed value.
Literals
Literals are the most obvious kind of constants. They are used to express particular values within the source code of
a program. We have already used some in previous chapters to give specific values to variables or to express
messages we wanted our programs to print out, for example, when we wrote:
a = 5;
Literal constants can be classified into: integer, floating-point, characters, strings, Boolean, pointers, and user-
defined literals.
Integer Numerals
1 1776
2 707
3 -273
These are numerical constants that identify integer values. Notice that they are not enclosed in quotes or any other
special character; they are a simple succession of digits representing a whole number in decimal base; for
example, 1776 always represents the value one thousand seven hundred seventy-six.
In addition to decimal numbers (those that most of us use every day), C++ allows the use of octal numbers (base 8)
and hexadecimal numbers (base 16) as literal constants. For octal literals, the digits are preceded with a 0 (zero)
character. And for hexadecimal, they are preceded by the characters 0x (zero, x). For example, the following literal
constants are all equivalent to each other:
1 75 // decimal
2 0113 // octal
3 0x4b // hexadecimal
All of these represent the same number: 75 (seventy-five) expressed as a base-10 numeral, octal numeral and
hexadecimal numeral, respectively.
These literal constants have a type, just like variables. By default, integer literals are of type int. However, certain
suffixes may be appended to an integer literal to specify a different integer type:
u or U unsigned
l or L long
ll or LL long long
Unsigned may be combined with any of the other two in any order to form unsigned long or unsigned long
long.
For example:
1 75 // int
2 75u // unsigned int
3 75l // long
4 75ul // unsigned long
5 75lu // unsigned long
In all the cases above, the suffix can be specified using either upper or lowercase letters.
1 3.14159 // 3.14159
2 6.02e23 // 6.02 x 10^23
3 1.6e-19 // 1.6 x 10^-19
4 3.0 // 3.0
These are four valid numbers with decimals expressed in C++. The first number is PI, the second one is the number of
Avogadro, the third is the electric charge of an electron (an extremely small number) -all of them approximated-, and
the last one is the number three expressed as a floating-point numeric literal.
The default type for floating-point literals is double. Floating-point literals of type float or long double can be
specified by adding one of the following suffixes:
Suffix Type
f or F float
l or L long double
For example:
Any of the letters that can be part of a floating-point numerical constant (e, f, l) can be written using either lower or
uppercase letters with no difference in meaning.
1 'z'
2 'p'
3 "Hello world"
4 "How do you do?"
The first two expressions represent single-character literals, and the following two represent string
literals composed of several characters. Notice that to represent a single character, we enclose it between single
quotes ('), and to express a string (which generally consists of more than one character), we enclose the characters
between double quotes (").
Both single-character and string literals require quotation marks surrounding them to distinguish them from possible
variable identifiers or reserved keywords. Notice the difference between these two expressions:
x
'x'
Here, x alone would refer to an identifier, such as the name of a variable or a compound type,
whereas 'x' (enclosed within single quotation marks) would refer to the character literal 'x' (the character that
represents a lowercase x letter).
Character and string literals can also represent special characters that are difficult or impossible to express otherwise
in the source code of a program, like newline (\n) or tab (\t). These special characters are all of them preceded by a
backslash character (\).
Here you have a list of the single character escape codes:
\n newline
\r carriage return
\t tab
\v vertical tab
\b backspace
\a alert (beep)
\\ backslash (\)
For example:
'\n'
'\t'
"Left \t Right"
"one\ntwo\nthree"
Internally, computers represent characters as numerical codes: most typically, they use one extension of
the ASCII character encoding system (see ASCII code for more info). Characters can also be represented in literals
using its numerical code by writing a backslash character (\) followed by the code expressed as an octal (base-8) or
hexadecimal (base-16) number. For an octal value, the backslash is followed directly by the digits; while for
hexadecimal, an x character is inserted between the backslash and the hexadecimal digits themselves (for
example: \x20 or \x4A).
Several string literals can be concatenated to form a single string literal simply by separating them by one or more
blank spaces, including tabs, newlines, and other valid blank characters. For example:
Note how spaces within the quotes are part of the literal, while those outside them are not.
Some programmers also use a trick to include long string literals in multiple lines: In C++, a backslash (\) at the end
of line is considered a line-continuation character that merges both that line and the next into a single line.
Therefore the following code:
1 x = "string expressed in \
2 two lines"
is equivalent to:
All the character literals and string literals described above are made of characters of type char. A different
character type can be specified by using one of the following prefixes:
u char16_t
U char32_t
L wchar_t
Note that, unlike type suffixes for integer literals, these prefixes are case sensitive: lowercase for char16_t and
uppercase for char32_t and wchar_t.
For string literals, apart from the above u, U, and L, two additional prefixes exist:
Prefix Description
In raw strings, backslashes and single and double quotes are all valid characters; the content of the literal is
delimited by an initial R"sequence( and a final )sequence", where sequence is any sequence of characters
(including an empty sequence). The content of the string is what lies inside the parenthesis, ignoring the delimiting
sequence itself. For example:
Both strings above are equivalent to "string with \\backslash". The R prefix can be combined with any other
prefixes, such as u, L or u8.
Other literals
Three keyword literals exist in C++: true, false and nullptr:
• true and false are the two possible values for variables of type bool.
• nullptr is the null pointer value.
Examples:
The variable declaration refers to the part where a variable is first declared or introduced before its first use.
A variable definition is a part where the variable is assigned a memory location and a value. Most of the
times, variable declaration and definition are done together.
#include <iostream>
using namespace std;
int main()
{
// declaration and definition
// of variable 'a123'
char a123 = 'a';
return 0;
}
Output:
a
C++ Operators:
An operator is a symbol that tells the compiler to perform specific mathematical or logical
manipulations. C++ is rich in built-in operators and provides the following types of operators −
• Arithmetic Operators
• Relational Operators
• Logical Operators
• Bitwise Operators
• Assignment Operators
• Misc Operators
This chapter will examine the arithmetic, relational, logical, bitwise, assignment and other
operators one by one.
Arithmetic Operators
Bitwise Operators
Bitwise operators work on bits and perform bit-by-bit operation. The truth tables for &, |, and ^ are
as follows −
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1
Assume if A = 60; and B = 13; now in binary format they will be as follows −
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
Assignment Operators
The following table lists some other operators that C++ supports.
1
sizeof
sizeof operator returns the size of a variable. For example, sizeof(a), where ‘a’ is
integer, and will return 4.
2
Condition ? X : Y
Conditional operator (?). If Condition is true then it returns value of X otherwise
returns value of Y.
3
,
Comma operator causes a sequence of operations to be performed. The value of
the entire comma expression is the value of the last expression of the comma-
separated list.
4
. (dot) and -> (arrow)
Member operators are used to reference individual members of classes,
structures, and unions.
5
Cast
Casting operators convert one data type to another. For example, int(2.2000)
would return 2.
6
&
Pointer operator & returns the address of a variable. For example &a; will give
actual address of the variable.
7
*
Pointer operator * is pointer to a variable. For example *var; will pointer to a
variable var.
C++ Enum:
Enumerated Types or Enums in C++
Enumerated type (enumeration) is a user-defined data type which can be assigned some limited values. These
values are defined by the programmer at the time of declaring the enumerated type.
When we assign a float value in a character value then compiler generates an error in the same way if we try to
assign any other value to the enumerated data types the compiler generates an error. Enumerator types of
values are also known as enumerators. It is also assigned by zero the same as the array.
It can also be used with switch statements.
For example: If a gender variable is created with value male or female. If any other value is assigned other
than male or female then it is not appropriate. In this situation, one can declare the enumerated type in which
only male and female values are assigned.
Enumeration in C++
Enum is a user defined data type where we specify a set of values for a variable and
the variable can only take one out of a small set of possible values. We use enum
keyword to define a Enumeration.
Syntax:
enum enumerated-type-name{value1, value2, value3…..valueN};
enum keyword is used to declare enumerated types after that enumerated type name was written then under
curly brackets possible values are defined. After defining Enumerated type variables are created. It can be
created in two types:-
1. It can be declared during declaring enumerated types, just add the name of the variable before the
semicolon. or,
2. Beside this, we can create enumerated type variables as same as the normal variables.
By default, the starting code value of the first element of enum is 0 (as in the case of array). But it can be
changed explicitly.
For example: enum enumerated-type-name{value 1=1, value2, value3};
And, the consecutive values of the enum will have the next set of code value(s).
For example:
In this case,
first_enum e;
e=value3;
cout<<e;
Output:
11
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Defining enum Gender
enum Gender { Male, Female };
switch (gender)
{
case Male:
cout << "Gender is Male";
break;
case Female:
cout << "Gender is Female";
break;
default:
cout << "Value can be Male or Female";
}
return 0;
}
Output:
Gender is Male
C++ Enumeration
Enum in C++ is a data type that contains fixed set of constants.
It can be used for days of the week (SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY and
SATURDAY) , directions (NORTH, SOUTH, EAST and WEST) etc. The C++ enum constants are static and final implicitly.
C++ Enums can be thought of as classes that have fixed set of constants.
It is possible for implicit conversions to lose information, signs can be lost (when signed is implicitly
converted to unsigned), and overflow can occur (when long long is implicitly converted to float).
#include <iostream>
using namespace std;
int main()
{
int x = 10; // integer x
char y = 'a'; // character c
return 0;
}
Output:
x = 107
y = a
z = 108
Explicit Type Conversion: This process is also called type casting and it is user-defined. Here the user can
typecast the result to make it of a particular data type.
In C++, it can be done by two ways:
• Converting by assignment: This is done by explicitly defining the required type in front of the
expression in parenthesis. This can be also considered as forceful casting.
Syntax:
(type) expression
Where type indicates the data type to which the final result is converted.
#include <iostream>
using namespace std;
int main()
{
double x = 1.2;
return 0;
}
Output:
Sum = 2
Conversion using Cast operator: A Cast operator is an unary operator which forces one data type to be
converted into another data type.
C++ supports four types of casting:
1. Static Cast
2. Dynamic Cast
3. Const Cast
4. Reinterpret Cast
• This is done to take advantage of certain features of type hierarchies or type representations.
• It helps to compute expressions containing variables of different data types.
C++ control structures:
Simple control structures
A program is usually not limited to a linear sequence of instructions. During its process it may bifurcate, repeat
code or take decisions. For that purpose, C++ provides control structures that serve to specify what has to be
done by our program, when and under which circumstances.
With the introduction of control structures we are going to have to introduce a new concept: the compound-
statement or block. A block is a group of statements which are separated by semicolons (;) like all C++
statements, but grouped together in a block enclosed in braces: { }:
Most of the control structures that we will see in this section require a generic statement as part of its syntax. A
statement can be either a simple statement (a simple instruction ending with a semicolon) or a compound
statement (several instructions grouped in a block), like the one just described. In the case that we want the
statement to be a simple statement, we do not need to enclose it in braces ({}). But in the case that we want the
statement to be a compound statement it must be enclosed between braces ({}), forming a block.
if (condition) statement
Where condition is the expression that is being evaluated. If this condition is true, statement is executed. If it is
false, statement is ignored (not executed) and the program continues right after this conditional structure.
For example, the following code fragment prints x is 100 only if the value stored in the x variable is indeed 100:
1 if (x == 100)
2 cout << "x is 100";
If we want more than a single statement to be executed in case that the condition is true we can specify a block
using braces { }:
1 if (x == 100)
2{
3 cout << "x is ";
4 cout << x;
5}
We can additionally specify what we want to happen if the condition is not fulfilled by using the keyword else. Its
form used in conjunction with if is:
For example:
1 if (x == 100)
2 cout << "x is 100";
3 else
4 cout << "x is not 100";
prints on the screen x is 100 if indeed x has a value of 100, but if it has not -and only if not- it prints out x is
not 100.
The if + else structures can be concatenated with the intention of verifying a range of values. The following
example shows its use telling if the value currently stored in x is positive, negative or none of them (i.e. zero):
1 if (x > 0)
2 cout << "x is positive";
3 else if (x < 0)
4 cout << "x is negative";
5 else
6 cout << "x is 0";
Remember that in case that we want more than a single statement to be executed, we must group them in a block
by enclosing them in braces { }.
Loops have as purpose to repeat a statement a certain number of times or while a condition is fulfilled.
and its functionality is simply to repeat statement while the condition set in expression is true.
For example, we are going to make a program to countdown using a while-loop:
int main ()
{
int n;
cout << "Enter the starting number > ";
cin >> n;
while (n>0) {
cout << n << ", ";
--n;
}
The whole process of the previous program can be interpreted according to the following script
(beginning in main):
Of course this is such a simple action for our computer that the whole countdown is performed instantly without
any practical delay between numbers.
Its functionality is exactly the same as the while loop, except that condition in the do-while loop is evaluated
after the execution of statement instead of before, granting at least one execution of statement even
if condition is never fulfilled. For example, the following example program echoes any number you enter until
you enter 0.
and its main function is to repeat statement while condition remains true, like the while loop. But in addition,
the for loop provides specific locations to contain an initialization statement and an increase statement. So
this loop is specially designed to perform a repetitive action with a counter which is initialized and increased on
each iteration.
1. initialization is executed. Generally it is an initial value setting for a counter variable. This is
executed only once.
2. condition is checked. If it is true the loop continues, otherwise the loop ends and statement is skipped
(not executed).
3. statement is executed. As usual, it can be either a single statement or a block enclosed in braces { }.
4. finally, whatever is specified in the increase field is executed and the loop gets back to step 2.
Here is an example of countdown using a for loop:
Optionally, using the comma operator (,) we can specify more than one expression in any of the fields included in
a for loop, like in initialization, for example. The comma operator (,) is an expression separator, it serves to
separate more than one expression where only one is generally expected. For example, suppose that we wanted
to initialize more than one variable in our loop:
This loop will execute for 50 times if neither n or i are modified within the loop:
n starts with a value of 0, and i with 100, the condition is n!=i (that n is not equal to i). Because n is increased
by one and i decreased by one, the loop's condition will become false after the 50th loop, when both n and i will
be equal to 50.
Jump statements.
The break statement
Using break we can leave a loop even if the condition for its end is not fulfilled. It can be used to end an infinite
loop, or to force it to end before its natural end. For example, we are going to stop the count down before its
natural end (maybe because of an engine check failure?):
#include <iostream>
using namespace std;
int main ()
{
int n;
for (n=10; n>0; n--)
{
cout << n << ", ";
if (n==3)
{
cout << "countdown aborted!";
break;
}
}
return 0;
}
The continue statement causes the program to skip the rest of the loop in the current iteration as if the end of
the statement block had been reached, causing it to jump to the start of the following iteration. For example, we
are going to skip the number 5 in our countdown:
Generally speaking, this instruction has no concrete use in structured or object oriented programming aside from
those that low-level programming fans may find for it. For example, here is our countdown loop using goto:
• Switch
• If
• If Else
• While
• Do While
• For
As shown in the flow charts:-
Selection structures
Selection structures are used to perform ‘decision making‘and then branch the program flow based on the
outcome of decision making. Selection structures are implemented in C/C++ with If, If Else and Switch
statements. If and If Else statements are 2 way branching statements where as Switch is a multi branching
statement.
The simple If statement
if (expression) // This expression is evaluated. If expression is TRUE statements inside the braces
will be executed
{
statement 1;
statement 2;
}
statement 1;// Program control is transferred directly to this line, if the expression is FALSE
statement 2;
The expression given inside the brackets after if is evaluated first. If the expression is true, then
statements inside the curly braces that follow if(expression) will be executed. If the expression is
false, the statements inside curly braces will not be executed and program control goes directly to
statements after curly braces.
if(expression 1)// Expression 1 is evaluated. If TRUE, statements inside the curly braces are
executed.
{ //If FALSE program control is transferred to immediate else if statement.
statement 1;
statement 2;
}
else if(expression 2)// If expression 1 is FALSE, expression 2 is evaluated.
{
statement 1;
statement 2;
}
else if(expression 3) // If expression 2 is FALSE, expression 3 is evaluated
{
statement 1;
statement 2;
}
else // If all expressions (1, 2 and 3) are FALSE, the statements that follow this else (inside curly
braces) is executed.
{
statement 1;
statement 2;
}
other statements;
The execution begins by evaluation expression 1. If it is TRUE, then statements inside the immediate curly
braces are evaluated. If it is FALSE, program control is transferred directly to immediate else if statement.
Here expression 2 is evaluated for TRUE or FALSE. The process continues. If all expressions inside the
different if and else if statements are FALSE, then the last else statement (without any expression) is
executed along with the statements 1 and 2 inside the curly braces of last else statement.
Switch statement
Note: - Switch statement is used for multiple branching. The same can be implemented
using nested “If Else” statements. But use of nested if else statements make program writing
tedious and complex. Switch makes it much easier. Compare this program with above one.
Loop structures:
A loop structure is used to execute a certain set of actions for a predefined number of times or until a
particular condition is satisfied. There are 3 control statements available in C/C++ to implement loop
structures.
Note: - while is an entry controlled loop. Statement inside braces are allowed to execute only if
condition inside while is TRUE.
The do while statement
Unlike while, do while is an exit controlled loop. Here the set of statements inside braces are executed first.
The condition inside while is checked only after finishing the first time execution of statements inside
braces. If the condition is TRUE, then statements are executed again. This process continues as long as
condition is TRUE. Program control exits the loop once the condition turns FALSE.
Note 1:- The statements given as "initialization statements" are executed only once, at the
beginning of a for loop.
Note 2: There are 3 statements given to a for loop as shown. One for initialization purpose,
other for condition testing and last one for iterating the loop. Each of these 3 statements
are separated by semicolons.
C++ Functions
The function in C++ language is also known as procedure or subroutine in other programming languages.
To perform any task, we can create function. A function can be called many times. It provides modularity
and code reusability.
1) Code Reusability:
By creating functions in C++, you can call it many times. So we don't need to write the same code
again and again.
2) Code optimization:
Types of Functions
There are two types of functions in C++ programming:
1. Library Functions: are the functions which are declared in the C++ header files such as ceil(x), cos(x),
exp(x), etc.
2. User-defined functions: are the functions which are created by the C++ programmer, so that he/she can
use it many times. It reduces complexity of a big program and optimizes the code.
Declaration of a function
The syntax of creating function in C++ language is given below:
#include <iostream>
using namespace std;
void func() {
static int i=0; //static variable
int j=0; //local variable
i++;
j++;
cout<<"i=" << i<<" and j=" <<j<<endl;
}
int main()
{
func();
func();
func();
}
Output:
i= 1 and j= 1
i= 2 and j= 1
i= 3 and j= 1
Call by value and call by reference in C++
There are two ways to pass value or data to function in C++ language: call by value and call by reference.
Original value is not modified in call by value but it is modified in call by reference.
In call by value, value being passed to the function is locally stored by the function parameter in stack
memory location. If you change the value of function parameter, it is changed for the current function only.
It will not change the value of variable inside the caller method such as main ().
Let's try to understand the concept of call by value in C++ language by the example given below:
#include <iostream>
using namespace std;
void change(int data);
int main()
{
int data = 3;
change(data);
cout << "Value of the data is: " << data<< endl;
return 0;
}
void change(int data)
{
data = 5;
}
Output:
Here, address of the value is passed in the function, so actual and formal arguments share the same address
space. Hence, value changed inside the function, is reflected inside as well as outside the function.
Note: To understand the call by reference, you must have the basic knowledge of pointers.
Let's try to understand the concept of call by reference in C++ language by the example given below:
#include<iostream>
using namespace std;
void swap(int *x, int *y)
{
int swap;
swap=*x;
*x=*y;
*y=swap;
}
int main()
{
int x=500, y=100;
swap(&x, &y); // passing value to function
cout<<"Value of x is: "<<x<<endl;
cout<<"Value of y is: "<<y<<endl;
return 0;
}
Output:
2 Changes made inside the function is not Changes made inside the function is
reflected on other functions reflected outside the function also
3 Actual and formal arguments will be Actual and formal arguments will be
created in different memory location created in same memory location
Return by reference in C++ with Examples:
Pointers and References in C++ held close relation with one another. The major difference is that the pointers
can be operated on like adding values whereas references are just an alias for another variable.
Return by reference is very different from Call by reference. Functions behave a very important role when
variable or pointers are returned as reference.
dataType& functionName(parameters);
where,
dataType is the return type of the function,
and parameters are the passed arguments to it
A C++ program can be made easier to read and maintain by using references rather than pointers. A C++
function can return a reference in a similar way as it returns a pointer.
When a function returns a reference, it returns an implicit pointer to its return value. This way, a function
can be used on the left side of an assignment statement. For example, consider this simple program −
#include <iostream>
#include <ctime>
When returning a reference, be careful that the object being referred to does not go out of scope. So it is not
legal to return a reference to local var. But you can always return a reference on a static variable.
In C, we have used Macro function an optimized technique used by compiler to reduce the execution time
etc. So Question comes in mind that what’s there in C++ for that and in what all better ways? Inline function
is introduced which is an optimization technique used by the compilers especially to reduce the execution
time. We will cover “what, why, when & how” of inline functions.
What is inline function: The inline functions are a C++ enhancement feature to increase the execution time
of a program. Functions can be instructed to compiler to make them inline so that compiler can replace those
function definition wherever those are being called. Compiler replaces the definition of inline functions at
compile time instead of referring function definition at runtime.
NOTE- This is just a suggestion to compiler to make the function inline, if function is big (in term of
executable instruction etc) then, compiler can ignore the “inline” request and treat the function as normal
function.
When the program executes the function call instruction the CPU stores the memory address of the instruction
following the function call, copies the arguments of the function on the stack and finally transfers control to the
specified function. The CPU then executes the function code, stores the function return value in a predefined
memory location/register and returns control to the calling function. This can become overhead if the
execution time of function is less than the switching time from the caller function to called function (callee).
For functions that are large and/or perform complex tasks, the overhead of the function call is usually
insignificant compared to the amount of time the function takes to run. However, for small, commonly-used
functions, the time needed to make the function call is often a lot more than the time needed to actually
execute the function’s code. This overhead occurs for small functions because execution time of small function
is less than the switching time.
C++ provides an inline functions to reduce the function call overhead. Inline function is a function that is
expanded in line when it is called. When the inline function is called whole code of the inline function gets
inserted or substituted at the point of inline function call. This substitution is performed by the C++ compiler at
compile time. Inline function may increase efficiency if it is small.
The syntax for defining the function inline is:
inline return-type function-name(parameters)
{
// function code
}
Remember, inlining is only a request to the compiler, not a command. Compiler can ignore the
request for inlining. Compiler may not perform inlining in such circumstances like:
How to make function inline: To make any function as inline, start its definitions with the keyword
“inline”.
Example –
Class A
{ Public:
inline int add(int a, int b)
{ return (a+ b);
};
}
Class A
{ Public:
int add(int a, int b);
};
inline int A::add(int a, in b)
{
return (a + b);
}
Why to use –
In many places we create the functions for small work/functionality which contain simple and less number
of executable instruction. Imagine their calling overhead each time they are being called by callers. When a
normal function call instruction is encountered, the program stores the memory address of the instructions
immediately following the function call statement, loads the function being called into the memory, copies
argument values, jumps to the memory location of the called function, executes the function codes, stores
the return value of the function, and then jumps back to the address of the instruction that was saved just
before executing the called function. Too much run time overhead.
The C++ inline function provides an alternative. With inline keyword, the compiler replaces the function
call statement with the function code itself (process called expansion) and then compiles the entire code.
Thus, with inline functions, the compiler does not have to jump to another location to execute the function,
and then jump back as the code of the called function is already available to the calling program.
With below pros, cons and performance analysis, you will be able to understand
the “why” for inline keyword
Pros:-
1. It speeds up your program by avoiding function calling overhead.
2. It save overhead of variables push/pop on the stack, when function calling happens.
3. It save overhead of return call from a function.
4. It increases locality of reference by utilizing instruction cache.
5. By marking it as inline, you can put a function definition in a header file (i.e. it can be included in
multiple compilation units, without the linker complaining)
Cons:-
1. It increases the executable size due to code expansion.
2. C++ inlining is resolved at compile time. Which means if you change the code of the inlined function,
you would need to recompile all the code using it to make sure it will be updated?
3. When used in a header, it makes your header file larger with information which users don’t care.
4. As mentioned above it increases the executable size, which may cause thrashing in memory. More
number of page fault bringing down your program performance.
5. Sometimes not useful for example in embedded system where large executable size is not preferred at all
due to memory constraints.
When to use -
Function can be made as inline as per programmer need. Some useful recommendation are mentioned
below-
Key Points -
1. it’s just a suggestion not compulsion. Compiler may or may not inline the functions you marked as inline.
It may also decide to inline functions not marked as inline at compilation or linking time.
2. Inline works like a copy/paste controlled by the compiler, which is quite different from a pre-processor
macro: The macro will be forcibly inlined, will pollute all the namespaces and code, won't be easy to debug.
3. All the member function declared and defined within class are Inline by default. So no need to define
explicitly.
4. Virtual methods are not supposed to be inlinable. Still, sometimes, when the compiler can know for sure
the type of the object (i.e. the object was declared and constructed inside the same function body), even a
virtual function will be inlined because the compiler knows exactly the type of the object.
5. Template methods/functions are not always inlined (their presence in an header will not make them
automatically inline).
6. Most of the compiler would do in-lining for recursive functions but some compiler provides #pragmas-
microsoft c++ compiler - inline_recursion(on) and once can also control its limit with inline_depth.
Inline functions provide following advantages:
1) Function call overhead doesn’t occur.
2) It also saves the overhead of push/pop variables on the stack when function is called.
3) It also saves overhead of a return call from a function.
4) When you inline a function, you may enable compiler to perform context specific optimization on the body
of function. Such optimizations are not possible for normal function calls. Other optimizations can be obtained
by considering the flows of calling context and the called context.
5) Inline function may be useful (if it is small) for embedded systems because inline can yield less code than
the function call preamble and return.
2) If you use too many inline functions then the size of the binary executable file will be large, because of the
duplication of same code.
3) Too much inlining can also reduce your instruction cache hit rate, thus reducing the speed of instruction
fetch from that of cache memory to that of primary memory.
4) Inline function may increase compile time overhead if someone changes the code inside the inline function
then all the calling location has to be recompiled because compiler would require to replace all the code once
again to reflect the changes, otherwise it will continue with old functionality.
5) Inline functions may not be useful for many embedded systems. Because in embedded systems code size is
more important than speed.
6) Inline functions might cause thrashing because inlining might increase size of the binary executable file.
Thrashing in memory causes performance of computer to degrade.
#include <iostream>
using namespace std;
class S
{
int m;
public:
#define MAC(S::m) // error
};
C++ compiler checks the argument types of inline functions and necessary conversions are performed
correctly. Preprocessor macro is not capable for doing this. One other thing is that the macros are managed by
preprocessor and inline functions are managed by C++ compiler. Remember: It is true that all the functions
defined inside the class are implicitly inline and C++ compiler will perform inline call of these functions, but
C++ compiler cannot perform inlining if the function is virtual. The reason is call to a virtual function is
resolved at runtime instead of compile time. Virtual means wait until runtime and inline means during
compilation, if the compiler doesn’t know which function will be called, how it can perform inlining?
Macros vs. Functions
Macros are pre-processed which means that all the macros would be processed before your program
compiles. However, functions are not preprocessed but compiled.
#include<stdio.h>
#define NUMBER 10
int main()
{
printf("%d", NUMBER);
return 0;
}
Output:
10
#include<stdio.h>
int number()
{
return 10;
}
int main()
{
printf("%d", number());
return 0;
}
Output:
10
This will give you the executable code as shown in the figure:
This shows that the macros are preprocessed while functions are not. In macros, no type checking
(incompatible operand, etc.) is done and thus use of micros can lead to errors/side-effects in some cases.
However, this is not the case with functions. Also, macros do not check for compilation error (if any).
Macros:
#include<stdio.h>
#define CUBE(b) b*b*b
int main()
{
printf("%d", CUBE(1+2));
return 0;
}
Functions:
#include<stdio.h>
int cube(int a)
{
return a*a*a;
}
int main()
{
printf("%d", cube(1+2));
return 0;
}
Output: As expected
27
• Macros are usually one liner. However, they can consist of more than one line, Click here to see the
usage. There are no such constraints in functions.
• The speed at which macros and functions differs. Macros are typically faster than functions as they
don’t involve actual function call overhead.
Conclusion:
Macros are no longer recommended as they cause following issues. There is a better way in modern compilers
that is inline functions and const variable. Below are disadvantages of macros:
a) There is no type checking
b) Difficult to debug as they cause simple replacement.
c) Macro doesn’t have namespace, so a macro in one section of code can affect other section.
d) Macros can cause side effects as shown in above CUBE () example.
BASIS FOR
INLINE MACRO
COMPARISON
Basic Inline functions are parsed by the compiler. Macros are expanded by the preprocessor.
Defined It can be defined inside or outside the class. It is always defined at the start of the program.
Evaluation It evaluates the argument only once. It evaluates the argument each time it is used in
the code.
Expansion The compiler may not inline and expands all Macros are always expanded.
the functions.
Automation The short functions, defined inside the class Macros should be defined specifically.
are automatically made onto inline functions.
Accessing An inline member function can access the Macros can never be the members of the class
data members of the class. and cannot access the data members of the class.
Termination Definition of inline function terminates with Definition of macro terminates with the new
the curly brackets at the end of the inline line.
function.
Debugging Debugging is easy for an inline function as Debugging becomes difficult for macros as error
error checking is done during compilation. checking does not occur during compilation.
Binding An inline function binds all the statements in A macro faces the binding problem if it has
the body of the function very well as the more than one statement, as it has no
body of the function start and ends with the termination symbol.
curly brackets.
MACRO FUNCTION
Speed of Execution using Macro is Faster Speed of Execution using Function is Slower
Before Compilation, macro name is replaced by During function call, transfer of control takes
macro value place
Macros are useful when small code is repeated many Functions are useful when large code is to be
times written
Macro does not check any Compile-Time Errors Function checks Compile-Time Errors
Overloading of functions:
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:
o methods,
o constructors, and
o indexed properties
o Function overloading
o Operator overloading
Function overloading is a C++ programming feature that allows us to have more than one function having
same name but different parameter list, when I say parameter list, it means the data type and sequence of the
parameters, for example the parameters list of a function myfuncn(int a, float b) is (int, float) which is
different from the function myfuncn(float a, int b) parameter list (float, int).
The advantage of Function overloading is that it increases the readability of the program because you don't
need to use different names for the same action.
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 plusFuncDouble(double x, double y) {
return x + y;
}
int main() {
int myNum1 = plusFuncInt(8, 5);
double myNum2 = plusFuncDouble(4.3, 6.26);
cout << "Int: " << myNum1 << "\n";
cout << "Double: " << myNum2;
return 0;
}
Instead of defining two functions that should do the same thing, it is better to overload one.
In the example below, we overload the plusFunc function to work for both int and double:
When the compiler is unable to decide which function is to be invoked among the overloaded function, this
situation is known as function overloading.
When the compiler shows the ambiguity error, the compiler does not run the program.
o Type Conversion.
o Function with default arguments.
o Function with pass by reference.
#include <iostream>
using namespace std;
class Addition {
public:
int sum(int num1,int num2) {
return num1+num2;
}
int sum(int num1,int num2, int num3) {
return num1+num2+num3;
}
};
int main(void) {
Addition obj;
cout<<obj.sum(20, 15)<<endl;
cout<<obj.sum(81, 100, 10);
return 0;
}
Output:
35
19
Default Arguments in C++
A default argument is a value provided in a function declaration that is automatically assigned by the compiler
if the caller of the function doesn’t provide a value for the argument with a default value.
Following is a simple C++ example to demonstrate the use of default arguments. We don’t have to write 3 sum
functions, only one function works by using default values for 3rd and 4th arguments.
#include<iostream>
using namespace std;
// A function with default arguments, it can be called with
// 2 arguments or 3 arguments or 4 arguments.
int sum(int x, int y, int z=0, int w=0)
{
return (x + y + z + w);
}
/* Driver program to test above function*/
int main()
{
cout << sum(10, 15) << endl;
cout << sum(10, 15, 25) << endl;
cout << sum(10, 15, 25, 30) << endl;
return 0;
}
Output:
25
50
80
When Function overloading is done along with default values. Then we need to make sure it will not be
ambiguous.
The compiler will throw error if ambiguous. Following is the modified version of above program.
#include<iostream>
using namespace std;
// A function with default arguments, it can be called with
// 2 arguments or 3 arguments or 4 arguments.
int sum(int x, int y, int z=0, int w=0)
{
return (x + y + z + w);
}
int sum(int x, int y, float z=0, float w=0)
{
return (x + y + z + w);
}
/* Driver program to test above function*/
int main()
{
cout << sum(10, 15) << endl;
cout << sum(10, 15, 25) << endl;
cout << sum(10, 15, 25, 30) << endl;
return 0;
}
Error:
prog.cpp: In function 'int main()':
prog.cpp:17:20: error: call of overloaded
'sum(int, int)' is ambiguous
cout << sum(10, 15) << endl;
^
prog.cpp:6:5: note: candidate:
int sum(int, int, int, int)
int sum(int x, int y, int z=0, int w=0)
^
prog.cpp:10:5: note: candidate:
int sum(int, int, float, float)
int sum(int x, int y, float z=0, float w=0)
^
Key Points:
• Default arguments are different from constant arguments as constant arguments can't be changed
whereas default arguments can be overwritten if required.
• Default arguments are overwritten when calling function provides values for them. For example,
calling of function sum(10, 15, 25, 30) overwrites the value of z and w to 25 and 30 respectively.
• During calling of function, arguments from calling function to called function are copied from left to
right. Therefore, sum(10, 15, 25) will assign 10, 15 and 25 to x, y, and z. Therefore, the default value is
used for w only.
• Once default value is used for an argument in function definition, all subsequent arguments to it must
have default value. It can also be stated as default arguments are assigned from right to left. For
example, the following function definition is invalid as subsequent argument of default variable z is
not default.
➢ If a function with default arguments is called without passing arguments, then the default parameters are used.
➢ However, if arguments are passed while calling the function, the default arguments are ignored.
We can understand the working of default arguments from the image above:
1. When temp() is called, both the default parameters are used by the function.
2. When temp(6) is called, the first argument becomes 6 while the default value is used
for the second parameter.
3. When temp(6, -2.3) is called, both the default parameters are overridden, resulting in i =
6 and f = -2.3.
4. When temp(3.4) is passed, the function behaves in an undesired way because the
second argument cannot be passed without passing the first argument.
Therefore, 3.4 is passed as the first argument. Since the first argument has been
defined as int, the value that is actually passed is 3.
Things to Remember:
1. Once we provide a default value for a parameter, all subsequent parameters must also have default values.
For example,
// Invalid
void add(int a, int b = 3, int c, int d);
// Invalid
void add(int a, int b = 3, int c, int d = 4);
// Valid
void add(int a, int c, int b = 3, int d = 4);
2. If we are defining the default arguments in the function definition instead of the function prototype, then
the function must be defined before the function call
// Invalid code
int main() {
// function call
display();
}
By using the keyword friend compiler knows the given function is a friend function.
For accessing the data, the declaration of a friend function should be done inside the body of a class
starting with the keyword friend.
In the above declaration, the friend function is preceded by the keyword friend. The function can be defined
anywhere in the program like a normal C++ function. The function definition does not use either the
keyword friend or scope resolution operator.
Characteristics of a Friend function:
o The function is not in the scope of the class to which it has been declared as a friend.
o It cannot be called using the object as it is not in the scope of that class.
o It can be invoked like a normal function without using the object.
o It cannot access the member names directly and has to use an object name and dot
membership operator with the member name.
o It can be declared either in the private or the public part.
1. Let's see the simple example of C++ friend function used to print the length of a box.
#include <iostream>
using namespace std;
class Box
{
private:
int length;
public:
Box(): length(0) { }
friend int printLength(Box); //friend function
};
int printLength(Box b)
{
b.length += 10;
return b.length;
}
int main()
{
Box b;
cout<<"Length of box: "<< printLength(b)<<endl;
return 0;
}
Output:
Length of box: 10
2. Let's see a simple example when the function is friendly to two classes.
#include <iostream>
using namespace std;
class B; // forward declarartion.
class A
{
int x;
public:
void setdata(int i)
{
x=i;
}
friend void min(A,B); // friend function.
};
class B
{
int y;
public:
void setdata(int i)
{
y=i;
}
friend void min(A,B); // friend function
};
void min(A a,B b)
{
if(a.x<=b.y)
std::cout << a.x << std::endl;
else
std::cout << b.y << std::endl;
}
int main()
{
A a;
B b;
a.setdata(10);
b.setdata(20);
min(a,b);
return 0;
}
Output:
10
In the above example, min() function is friendly to two classes, i.e., the min() function can
access the private members of both the classes A and B.
C++ Friend class:
A friend class can access both private and protected members of the class in which it has been
declared as friend.
#include <iostream>
class A
{
int x =5;
friend class B; // friend class.
};
class B
{
public:
void display(A &a)
{
cout<<"value of x is : "<<a.x;
}
};
int main()
{
A a;
B b;
b.display(a);
return 0;
}
Output:
value of x is : 5
In the above example, class B is declared as a friend inside the class A. Therefore, B is a
friend of class A. Class B can access the private members of class A.
C++ Friend function:
o A C++ virtual function is a member function in the base class that you redefine in a derived
class. It is declared using the virtual keyword.
o It is used to tell the compiler to perform dynamic linkage or late binding on the function.
o There is a necessity to use the single pointer to refer to all the objects of the different classes.
So, we create the pointer to the base class that refers to all the derived objects. But, when base
class pointer contains the address of the derived class object, always executes the base class
function. This issue can only be resolved by using the 'virtual' function.
o A 'virtual' is a keyword preceding the normal declaration of a function.
o When the function is made virtual, C++ determines which function is to be invoked at the
runtime based on the type of the object pointed by the base class pointer.
A virtual function is a member function which is declared within a base class and is re-defined (Overridden)
by a derived class. When you refer to a derived class object using a pointer or a reference to the base class, you
can call a virtual function for that object and execute the derived class’s version of the function.
• Virtual functions ensure that the correct function is called for an object, regardless of the type of reference (or
pointer) used for function call.
• They are mainly used to achieve Runtime polymorphism
• Functions are declared with a virtual keyword in base class.
• The resolving of function call is done at Run-time.
#include <iostream>
using namespace std;
class A
{
int x=5;
public:
void display()
{
std::cout << "Value of x is : " << x<<std::endl;
}
};
class B: public A
{
int y = 10;
public:
void display()
{
std::cout << "Value of y is : " <<y<< std::endl;
}
};
int main()
{
A *a;
B b;
a = &b;
a->display();
return 0;
}
Output:
Value of x is: 5
In the above example, * a is the base class pointer. The pointer can only access the base class
members but not the members of the derived class. Although C++ permits the base pointer to point to
any object derived from the base class, it cannot directly access the members of the derived class.
Therefore, there is a need for virtual function which allows the base pointer to access the members of
the derived class.
C++ virtual function Example:
Let's see the simple example of C++ virtual function used to invoked the derived class in a program.
#include <iostream>
{
public:
virtual void display()
{
cout << "Base class is invoked"<<endl;
}
};
class B:public A
{
public:
void display()
{
cout << "Derived Class is invoked"<<endl;
}
};
int main()
{
A* a; //pointer of base class
B b; //object of derived class
a = &b;
a->display(); //Late Binding occurs
}
Output:
1. Virtual functions cannot be static and also cannot be a friend function of another class.
2. Virtual functions should be accessed using pointer or reference of base class type to achieve run time
polymorphism.
3. The prototype of virtual functions should be same in base as well as derived class.
4. They are always defined in base class and overridden in derived class. It is not mandatory for derived class to
override (or re-define the virtual function), in that case base class version of function is used.
5. A class may have virtual destructor but it cannot have a virtual constructor.
Example 2: C++ virtual Function
#include <iostream>
using namespace std;
class Base {
public:
virtual void print() {
cout << "Base Function" << endl;
}
};
int main() {
Derived derived1;
return 0;
}
Output
Derived Function
So, this function is overridden even when we use a pointer of Base type that points to
the Derived object derived1 .
Compile-time (early binding) VS run-time(late binding) behavior of Virtual Functions
Consider the following simple program showing run-time behavior of virtual functions.
#include <iostream>
using namespace std;
class base {
public:
virtual void print()
{
cout << "print base class" << endl;
}
void show()
{
cout << "show base class" << endl;
}
};
class derived : public base {
public:
void print()
{
cout << "print derived class" << endl;
}
void show()
{
cout << "show derived class" << endl;
}
};
int main()
{
base* bptr;
derived d;
bptr = &d;
Explanation: Runtime polymorphism is achieved only through a pointer (or reference) of base class type.
Also, a base class pointer can point to the objects of base class as well as to the objects of derived class.
In above code, base class pointer ‘bptr’ contains the address of object ‘d’ of derived class.
Late binding(Runtime) is done in accordance with the content of pointer (i.e. location pointed to by pointer)
and Early binding(Compile time) is done according to the type of pointer, since print() function is declared
with virtual keyword so it will be bound at run-time (output is print derived class as pointer is pointing to
object of derived class ) and show() is non-virtual so it will be bound during compile time(output is show base
class as pointer is of base type ).
NOTE: If we have created a virtual function in the base class and it is being overridden in the derived class
then we don’t need virtual keyword in the derived class, functions are automatically considered as virtual
functions in the derived class.
As discussed here, if a class contains a virtual function then compiler itself does two things:
1. If object of that class is created then a virtual pointer (VPTR) is inserted as a data member of the class to point
to VTABLE of that class. For each new object created, a new virtual pointer is inserted as a data member of that
class.
2. Irrespective of object is created or not, a static array of function pointer called VTABLE where each cell
contains the address of each virtual function contained in that class.