C++ HandBook
C++ HandBook
What is C++?
C++ is a cross-platform language that can be used to create high-
performance applications.
C++ gives programmers a high level of control over system resources and
memory.
C++ is portable and can be used to develop applications that can be adapted
to multiple platforms.
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.
Note: The body of int main() could also been written as:
int main () { cout << "Hello World! "; return 0; }
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.
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)
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 (>>)
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:
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 »
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:
and the same for all other compound assignment operators. For
example:
int main ()
{
int a, b=3;
a = b;
a+=2; // equivalent to a=a+2
cout << a;
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.
operat
description
or
== Equal to
!= Not equal to
< Less than
> Greater than
Less than or equal
<=
to
Greater than or
>=
equal to
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
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
|| 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 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;
C++ Strings
Strings are used for storing text.
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;
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 [].
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.
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;
}
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";
}
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.";
}
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."
Syntax
variable = (condition) ? expressionTrue : expressionFalse;
Syntax
switch(expression) {
case x:
// code block
break;
case y:
// code block
break;
default:
// code block
}
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)
Statement 1 is executed (one time) before the execution of the code block.
Statement 3 is executed (every time) after the code block has been
executed.
Example
for (int i = 0; i < 5; i++) {
cout << i << "\n";
}
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.
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.
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:
string cars[4];
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:
int main () {
// an array with 5 rows and 2 columns.
int a[5][2] = { {0,0},
{1,2},
{2,4},
{3,6},
{4,8}};
cout << "a[" << i << "][" << j << "]: ";
cout << a[i][j]<< endl;
}
}
return 0;
}
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.
Example
Assign data to members of a structure and print it:
struct {
int myNum;
string myString;
} myStruct1, myStruct2, myStruct3; // Multiple structure
variables separated with commas
struct {
string brand;
string model;
int year;
} myCar1, myCar2; // We can add variables by separating them with
a comma here
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:
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:
int main() {
// Create a car structure and store it in myCar1;
car myCar1;
myCar1.brand = "BMW";
myCar1.model = "X5";
myCar1.year = 1999;
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;
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;
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
Pointer to Constant
#include <iostream>;
int main()
{
int myVar ;
int *myPointer;
myVar = 8;
myPointer = &myVar;
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?
Creating References
A reference variable is a "reference" to an existing variable, and it is created
with the & operator:
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;
References Pointers
It is storing the
It is referring to
address of the
another variable.
Work variable.
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.
int main()
{
int i;
do {
cout << "Please, enter number (0 to exit): ";
cin >> i;
odd (i);
} while (i!=0);
return 0;
}
#include <iostream>
using namespace std;
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;
}
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;
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;
int main ()
{
long number = 9;
cout << number << "! = " << factorial (number);
return 0;
}
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.
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
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":
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:
int main() {
MyClass `; // Create an object of MyClass
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;
#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.
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
};
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);
};
Access Specifiers
In C++, there are three access specifiers:
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>
// 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);
return 0;
}
// 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;
}
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
class Line {
public:
void setLength( double len );
double getLength( void );
Line(); // This is the constructor
private:
double length;
};
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>
private:
double length;
};
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
private:
double length;
};
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
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. }
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
Overview:
Overview:
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();
C++
// Explicitly copy constructor Calling
#include<iostream>
class Sample
int id;
public:
void init(int x)
id=x;
{
id=t.id;
void display()
cout<<endl<<"ID="<<id;
};
int main()
Sample obj1;
obj1.init(10);
obj1.display();
obj2.display();
return 0;
#include <cstring>
#include <iostream>
class String {
private:
char* s;
int size;
public:
void print()
};
size = strlen(str);
strcpy(s, str);
delete[] s;
size = strlen(str);
strcpy(s, str);
size = old_str.size;
strcpy(s, old_str.s);
int main()
String str1("GeeksQuiz");
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>
class String
private:
char *s;
int size;
public:
};
size = strlen(str);
s = new char[size+1];
strcpy(s, str);
delete [] s;
size = strlen(str);
s = new char[size+1];
strcpy(s, str);
int main()
String str1("GeeksQuiz");
str2.print();
str2.change("GeeksforGeeks");
str2.print();
return 0;
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;
}
// Driver code
int main()
{
Complex c1(10, 5), c2(2, 4);
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);
//base.cpp File
#include "PolymorphismClass.h"
#include "ChildPolyClass.h"
#include "ChildChildClass.h"
PolymorphismClass::PolymorphismClass(void)
{
}
PolymorphismClass::~PolymorphismClass(void)
{
}
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);
//child class.cpp
#include "ChildPolyClass.h"
ChildPolyClass::ChildPolyClass(void)
{
}
ChildPolyClass::~ChildPolyClass(void)
{
}
class OverrideBaseClass
{
public:
OverrideBaseClass(void);
~OverrideBaseClass(void);
};
// base.cpp
#include "OverrideBaseClass.h"
OverrideBaseClass::OverrideBaseClass(void)
{
}
OverrideBaseClass::~OverrideBaseClass(void)
{
}
// child.h
#pragma once
#include "overridebaseclass.h"
// child.cpp
#include "OverrideChildClass.h"
OverrideChildClass::OverrideChildClass(void)
{
}
OverrideChildClass::~OverrideChildClass(void)
{
}
//main.cpp
#include <iostream>
#include "OverrideBaseClass.h"
#include "OverrideChildClass.h"
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
return 0;
}
//Base Class
#pragma once
class BaseClass
{
public:
BaseClass(void);
~BaseClass(void);
#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"
};
#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>
// 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;
}
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 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.
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);
// base.cpp
#include "EmployeeClass.h"
EmployeeClass::EmployeeClass(void)
{
}
EmployeeClass::~EmployeeClass(void)
{
}
.
.
.
#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
return 0;
}
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.
#include <iostream>
using namespace std;
public:
// pure virtual function
virtual void fun() = 0;
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);
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. }
The classes which are containing The classes which are containing pure
virtual functions are not abstract virtual function are the abstract classes.
classes.
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;
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.
#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);
obj1.print();
return 0;
}
Output:
x = 10 y = 20
int main()
{
// All these variables get memory
// allocated on stack
int a;
int b[10];
int n = 20;
int c[n];
}
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 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.
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.
// Driver Code
int main()
{
// Creation of ofstream class object
ofstream fout;
string line;
// Press -1 to exit
if (line == "-1")
break;
return 0;
}
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>
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;
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:
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.
Access elements
Change elements
Remove elements
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> num {1, 2, 3, 4, 5};
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,
num.push_back(6);
num.push_back(7);
Note: We can also use the insert() and emplace() functions to add
elements to a vector.
int main() {
vector<int> num {1, 2, 3, 4, 5};
return 0;
}
Run Code
Output
Element at Index 0: 1
Element at Index 2: 3
Element at Index 4: 5
Here,
// 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};
return 0;
}
Run Code
Output
Initial Vector: 1 2 3 4 5
Updated Vector: 1 9 3 4 7
num.at(1) = 9;
num.at(4) = 7;
int main() {
vector<int> prime_numbers{2, 3, 5, 7};
// initial vector
cout << "Initial Vector: ";
for (int i : prime_numbers) {
cout << i << " ";
}
// 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
prime_numbers.pop_back();
Here, we have removed the last element (7) from the vector.
Function Description
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:
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] .
int main() {
vector<int> num {1, 2, 3, 4, 5};
// declare iterator
vector<int>::iterator 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.
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.
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.
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 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;
}