UNIT 2 OOP Notes
UNIT 2 OOP Notes
User-Defined DataTypes: The data types that are defined by the user are called the
derived datatype or user-defined derived data type.
These types include:
Class
Structure
Union
Enumeration
Typedef defined Data Type
Class: The building block of C++ that leads to Object-Oriented programming is a Class. It
is a user-defined data type, which holds its own data members and member functions,
which can be accessed and used by creating an instance of that class. A class is like a
blueprint for an object.
Structure: A structure is a user defined data type in C/C++. A structure creates a data type
that can be used to group items of possibly different types into a single type.
Syntax:
struct address {
char name[50];
char street[100];
char city[50];
char state[20];
int pin;
};
Union: Like Structures, union is a user defined data type. In union, all members share the
same memory location. For example in the following C program, both x and y share the
same location. If we change x, we can see the changes being reflected in y.
Enumeration: Enumeration (or enum) is a user defined data type in C. It is mainly used to
assign names to integral constants, the names make a program easy to read and maintain.
Syntax:
enum State {Working = 1, Failed = 0};
Example:
enum week_days{sun, mon, tues, wed, thur, fri, sat};
int main()
enum week_days d;
d = mon;
cout << d;
return 0;
}
Typedef : C++ allows you to define explicitly new data type names by using the keyword
typedef. Using typedef does not actually create a new data class, rather it defines a name for
an existing type. This can increase the portability(the ability of a program to be used across
different types of machines; i.e., mini, mainframe, micro, etc; without much changes into
the code)of a program as only the typedef statements would have to be changed. Using
typedef one can also aid in self-documenting code by allowing descriptive names for the
standard data types.
Syntax:
typedef type name;
Example
typedef int score;
int main()
{
s1 = 80;
return 0;
The user of data type does not need to know how that data type is implemented, for
example, we have been using Primitive values like int, float, char data types only with the
knowledge that these data type can operate and be performed on without any idea of how
they are implemented.
So a user only needs to know what a data type can do, but not how it will be implemented.
Think of ADT as a black box which hides the inner structure and design of the data type.
Now we‟ll define three ADTs namely List ADT, Stack ADT, Queue ADT.
1. List ADT
The data is generally stored in key sequence in a list which has a head structure
consisting of count, pointers and address of compare function needed to compare the
data in the list.
The data node contains the pointer to a data structure and a self-referential
pointer which points to the next node in the list.
The List ADT Functions is given below:
get() – Return an element from the list at any given position.
insert() – Insert an element at any position of the list.
remove() – Remove the first occurrence of any element from a non-empty list.
removeAt() – Remove the element at a specified location from a non-empty list.
replace() – Replace an element at any position by another element.
size() – Return the number of elements in the list.
isEmpty() – Return true if the list is empty, otherwise return false.
isFull() – Return true if the list is full, otherwise return false.
2. Stack ADT
In Stack ADT Implementation instead of data being stored in each node, the pointer to
data is stored.
The program allocates memory for the data and address is passed to the stack ADT.
The head node and the data nodes are encapsulated in the ADT. The calling function
can only see the pointer to the stack.
The stack head structure also contains a pointer to top and count of number of entries
currently in stack.
push() – Insert an element at one end of the stack called top.
pop() – Remove and return the element at the top of the stack, if it is not empty.
peek() – Return the element at the top of the stack without removing it, if the stack is
not empty.
size() – Return the number of elements in the stack.
isEmpty() – Return true if the stack is empty, otherwise return false.
isFull() – Return true if the stack is full, otherwise return false.
3. Queue ADT
The queue abstract data type (ADT) follows the basic design of the stack abstract data
type.
Each node contains a void pointer to the data and the link pointer to the next element in
the queue. The program‟s responsibility is to allocate memory for storing the data.
enqueue() – Insert an element at the end of the queue.
dequeue() – Remove and return the first element of the queue, if the queue is not empty.
peek() – Return the element of the queue without removing it, if the queue is not empty.
size() – Return the number of elements in the queue.
isEmpty() – Return true if the queue is empty, otherwise return false.
isFull() – Return true if the queue is full, otherwise return false.
Features of ADT: Abstract data types (ADTs) are a way of encapsulating data and
operations on that data into a single unit. Some of the key features of ADTs include:
Abstraction: The user does not need to know the implementation of the data structure
only essentials are provided.
Better Conceptualization: ADT gives us a better conceptualization of the real world.
Robust: The program is robust and has the ability to catch errors.
Encapsulation: ADTs hide the internal details of the data and provide a public interface
for users to interact with the data. This allows for easier maintenance and modification
of the data structure.
Data Abstraction: ADTs provide a level of abstraction from the implementation details
of the data. Users only need to know the operations that can be performed on the data,
not how those operations are implemented.
Data Structure Independence: ADTs can be implemented using different data
structures, such as arrays or linked lists, without affecting the functionality of the ADT.
Information Hiding: ADTs can protect the integrity of the data by allowing access
only to authorized users and operations. This helps prevent errors and misuse of the
data.
Modularity: ADTs can be combined with other ADTs to form larger, more complex
data structures. This allows for greater flexibility and modularity in programming.
Overall, ADTs provide a powerful tool for organizing and manipulating data in a structured
and efficient manner.
Abstract data types (ADTs) have several advantages and disadvantages that should be
considered when deciding to use them in software development. Here are some of the main
advantages and disadvantages of using ADTs:
Advantages:
Encapsulation: ADTs provide a way to encapsulate data and operations into a single
unit, making it easier to manage and modify the data structure.
Abstraction: ADTs allow users to work with data structures without having to know
the implementation details, which can simplify programming and reduce errors.
Data Structure Independence: ADTs can be implemented using different data
structures, which can make it easier to adapt to changing needs and requirements.
Information Hiding: ADTs can protect the integrity of data by controlling access and
preventing unauthorized modifications.
Modularity: ADTs can be combined with other ADTs to form more complex data
structures, which can increase flexibility and modularity in programming.
Disadvantages:
Overhead: Implementing ADTs can add overhead in terms of memory and processing,
which can affect performance.
Complexity: ADTs can be complex to implement, especially for large and complex
data structures.
Learning Curve: Using ADTs requires knowledge of their implementation and usage,
which can take time and effort to learn.
Limited Flexibility: Some ADTs may be limited in their functionality or may not be
suitable for all types of data structures.
Cost: Implementing ADTs may require additional resources and investment, which can
increase the cost of development.
Overall, the advantages of ADTs often outweigh the disadvantages, and they are widely
used in software development to manage and manipulate data in a structured and efficient
way. However, it is important to consider the specific needs
and requirements of a project when deciding whether to use ADTs.
From these definitions, we can clearly see that the definitions do not specify how these
ADTs will be represented and how the operations will be carried out. There can be different
ways to implement an ADT, for example, the List ADT can be implemented using arrays,
or singly linked list or doubly linked list. Similarly, stack ADT and Queue ADT can be
implemented using arrays or linked lists.
C++ Operators
Operators are symbols that perform operations on variables and values. For example, + is an
operator used for addition, while - is an operator used for subtraction.
Operators in C++ can be classified into 6 types:
1. Arithmetic Operators
2. Assignment Operators
3. Relational Operators
4. Logical Operators
5. Bitwise Operators
6. Other Operators
1. C++ Arithmetic Operators
Arithmetic operators are used to perform arithmetic operations on variables and data. For
example,
a + b;
Here, the + operator is used to add two variables a and b. Similarly there are various other
arithmetic operators in C++.
Operator Operation
+ Addition
- Subtraction
* Multiplication
/ Division
int main() {
int a, b;
a = 7;
b = 2;
return 0;
}
Run Code
Output
a+b=9
a-b=5
a * b = 14
a/b=3
a%b=1
Here, the operators +, - and * compute addition, subtraction, and multiplication respectively
as we might have expected.
/ Division Operator
Note the operation (a / b) in our program. The / operator is the division operator.
As we can see from the above example, if an integer is divided by another integer, we will get
the quotient. However, if either divisor or dividend is a floating-point number, we will get the
result in decimals.
In C++,
7/2 is 3
7.0 / 2 is 3.5
7 / 2.0 is 3.5
7.0 / 2.0 is 3.5
% Modulo Operator
The modulo operator % computes the remainder. When a = 9 is divided by b = 4, the
remainder is 1.
int num = 5;
// increment operator
++num; // 6
#include <iostream>
using namespace std;
int main() {
int a = 10, b = 100, result_a, result_b;
return 0;
}
Run Code
Output
result_a = 11
result_b = 99
In the above program, we have used the ++ and -- operators as prefixes (++a and --b).
However, we can also use these operators as postfix (a++ and b--).
To learn more, visit increment and decrement operators.
2. C++ Assignment Operators
In C++, assignment operators are used to assign values to variables. For example,
// assign 5 to a
a = 5;
= a = b; a = b;
+= a += b; a = a + b;
-= a -= b; a = a - b;
*= a *= b; a = a * b;
/= a /= b; a = a / b;
%= a %= b; a = a % b;
int main() {
int a, b;
// 2 is assigned to a
a = 2;
// 7 is assigned to b
b = 7;
return 0;
}
Run Code
Output
a=2
b=7
After a += b;
a=9
3. C++ Relational Operators
A relational operator is used to check the relationship between two operands. For example,
int main() {
int a, b;
a = 3;
b = 5;
bool result;
result = (a == b); // false
cout << "3 == 5 is " << result << endl;
return 0;
}
Run Code
Output
3 == 5 is 0
3 != 5 is 1
3 > 5 is 0
3 < 5 is 1
3 >= 5 is 0
3 <= 5 is 1
Logical OR.
|| expression1 || expression2 True if at least one of the operands is
true.
Logical NOT.
! !expression
True only if the operand is false.
In C++, logical operators are commonly used in decision making. To further understand the
logical operators, let's see the following examples,
Suppose,
a=5
b=8
Then,
int main() {
bool result;
return 0;
}
Run Code
Output
(3 != 5) && (3 < 5) is 1
(3 == 5) && (3 < 5) is 0
(3 == 5) && (3 > 5) is 0
(3 != 5) || (3 < 5) is 1
(3 != 5) || (3 > 5) is 1
(3 == 5) || (3 > 5) is 0
!(5 == 2) is 1
!(5 == 5) is 0
Operator Description
^ Binary XOR
later tutorials.
Boolean Logic
Boolean values on their own do not appear to be very useful, however when combined with
control statements they become one of the most powerful tools that any programing language
has to offer. As stated in the data types notes, boolean variables (bool) can be either true or
false. There are also binary operators that return a boolean value depending on specific
conditions. Some operators compare, such as ==, !=, >, etc., the values on either side of it and
return true if the entire statement is true. Others, work with boolean values to return another
boolean, such as && and ||.
Greater
Returns true if the first term is greater than or equal to the
Than or >= x >= 0
second, otherwise it returns false.
Equal
Less Than Returns true if the first term is less than or equal to the
<= x <= -2
or Equal second, otherwise it returns false.
x && True
Returns true if both terms on either side of the operator
(x == 2)
And && are true, otherwise it returns false. It is commonly used to
&& (y >=
concatenate statements together.
0)
Control Statements
Control Statements in C++:
In C++, Control Statements are usually jumped from one part of the C++ code to another
depending on whether a particular condition is satisfied or not. There are three types of C++
Control Statements are given as follows:
1. Sequence Statement
2. Selection Statement
3. Loop Statement
A C++ control statement redirects the flow of a program in order to execute additional code.
These statements come in the form of conditionals and loops.Each of them relies on a logical
condition that evaluates to a boolean value in order to run one piece of code over another.
1. if Statement
2. if-else Statement
3. Nested if Statement
4. if-else-if Ladder
5. switch Statement
6. Conditional Operator
7. Jump Statements:
break
continue
goto
return
if Statement:
The if statement is the simplest of the three and is used to run a certain piece of code nly if a
certain condition is true. For example: int x = 5;
if (x == 5) {
std::cout << "x is 5" << std::endl;
}
In this example, the block of code inside the curly braces will only be executed if the
condition inside the parentheses is true.
If-Else
If-Else statements allow the program to execute different blocks of code depending on
conditionals. All If statements have the following form:
if ( condition ) {
//body
}
An If statement executes the code in the body section if the condition evaluates to True,
otherwise it skips the body. When the condition evaluates to False, the program will either
test another condition with a following Else-if, run the code inside an Else statement, or
continue as normal if neither an Else-if nor Else block exist. An Else statement acts as a
default case for If statements. In the case that an If is directly followed by an Else and the
condition is false, the code in the Else is executed. Else statements do not have a condition
themselves.
if ( condition ) {
//body
} else {
// else body
}
An If statement can followed by any number of Else-if blocks. Each Else-if has its own
conditional statement and body of code. If an Else-if conditional is False, then its body of
code is skipped and the program will check the next Else-if in order that they appear. An If
followed by a long list of Else-IF's is usually referred to as an If-Else ladder.
if ( condition ) {
//body
} else if ( 2nd condition ) {
// else if body
} else {
// else body
}
Loops:
Loops are used in C++ to execute a block of code multiple times, either until a certain
condition is met or for a specific number of times. There are generally three types of loops in
C++: while, do-while, and for.
For Loop
A for loop allows for a block of code to be executed until a conditional becomes false. For
loops are usually used when a block of code needs to executed a fixed number of times. Each
loop consists of 3 parts, an initialization step, the conditional, and an iteration step. The
initialization is run before entering the loop, the condition is checked at the beginning of each
run through the loop ( including the first run ), and the iteration step executes at the end of
each pass through the loop, but before the condition is rechecked. It is usual practice to have
the iteration step move the loop on step closer to making the condition false, thus ending the
loop, but this does not need to be the case.
for( initialization ; conditional ; iteration ) {
// loop body
}
While Loop
A while loop is a simple loop that will run the same code over and over as long as a given
conditional is true. The condition is checked at the beginning of each run through the loop (
including the first one ). If the conditional is false for the beginning, the while loop will be
skipped all together.
while ( conditional ) {
// loop body
}
Do-while Loop
A do-while loop acts just like a while loop, except the condition is checked at the end of each
pass through the loop body. This means a do-while loop will execute at least once.
do {
// loop body
} while ( condition );
Break
Break is a useful keyword that allows the program to exit a loop or switch statement before
the expected end of a that code block. This is useful in error checking or if the outcome of a
loop is not certain. For example, the following code will break out of the for loop if a user
asks to leave.
string inputs[10];
string input;
for (int i = 0; i < 10; i++ ) {
cin >> input;
if ( input == "quit" ) {
break;
}
inputs[i] = input;
}
goto Statement
Syntax of goto statement:
goto pgr;
|||
pgr :
pgr is known as label. It is a user defined identifier. After the execution of goto statement, the
control transfers to the line after label pgr.
It is not a good programming to use goto statement in a program.
continue Statement
The continue statement is used in loops and causes a program to skip the rest of the body of
the loop.
while (condition)
{
statement 1;
If (condition)
continue ;
statement 2;
}
statement 3;
exit ( ) function
The execution of a program can be stopped at any point with exit ( ) and a status code can be
informed to the calling program. The general format is:
exit (code) ;
where code is an integer value. The code has a value 0 for correct execution. The value of the
code varies depending upon the operating system. It requires a process.h header file.
switch statement:
It is multiple branching statement where based on a condition, the control is transferred to
one of the many possible points. It has the following syntax:
switch(expression)
{
case1:
{
action 1;
}
case 2:
{
action 2;
}
case 3:
{
action 3;
}
default:
{
default statement;
Example
Inside main, call myFunction():
// Create a function
void myFunction() {
cout << "I just got executed!";
}
int main() {
myFunction(); // call the function
return 0;
}
// Outputs "I just got executed!"
A function can be called multiple times:
Example
void myFunction() {
cout << "I just got executed!\n";
}
int main() {
myFunction();
myFunction();
myFunction();
return 0;
}
// I just got executed!
// I just got executed!
// I just got executed!
Function Declaration and Definition
A C++ function consist of two parts:
Declaration: the return type, the name of the function, and parameters (if any)
Definition: the body of the function (code to be executed)
void myFunction()
{ // declaration
// the body of the function (definition)
}
If a user-defined function, such as myFunction() is declared after the main() function, an
error will occur:
Example
int main() {
myFunction();
return 0;
}
void myFunction()
{
cout << "I just got executed!";
}
You will often see C++ programs that have function declaration above main(), and function
definition below main(). This will make the code better organized and easier to read:
Example
// Function declaration
void myFunction();
// The main method
int main() {
myFunction(); // call the function
return 0;
}
// Function definition
void myFunction() {
cout << "I just got executed!";
}
A function is a block of code that performs a specific task.
Suppose we need to create a program to create a circle and color it. We can create two
functions to solve this problem:
a function to draw the circle
a function to color the circle
Dividing a complex problem into smaller chunks makes our program easy to understand and
reusable.
There are two types of function:
1. Standard Library Functions: Predefined in C++
2. User-defined Function: Created by users
In this tutorial, we will focus mostly on user-defined functions.
C++ User-defined Function
C++ allows the programmer to define their own function.
A user-defined function groups code to perform a specific task and that group of code is
given a name (identifier).
When the function is invoked from any part of the program, it all executes the codes defined
in the body of the function.
C++ Function Declaration
The syntax to declare a function is:
returnType functionName (parameter1, parameter2,...) {
// function body
}
void greet() {
cout << "Hello World";
}
Here,
the name of the function is greet()
the return type of the function is void
the empty parentheses mean it doesn't have any parameters
the function body is written inside {}
Note: We will learn about returnType and parameters later in this tutorial.
Calling a Function
In the above program, we have declared a function named greet(). To use
the greet() function, we need to call it.
Here's how we can call the above greet() function.
int main() {
// calling a function
greet();
// declaring a function
void greet() {
cout << "Hello there!";
}
int main() {
return 0;
}
Output
Hello there!
Function Parameters
s mentioned above, a function can be declared with parameters (arguments). A parameter is a
value that is passed when declaring a function.
For example, let us consider the function below:
nt main() {
int n = 7;
return 0;
}
#include <iostream>
using namespace std;
// display a number
void displayNum(int n1, float n2) {
cout << "The int number is " << n1;
cout << "The double number is " << n2;
}
int main() {
int num1 = 5;
double num2 = 5.5;
return 0;
}
Run Code
Output
void displayNumber() {
// code
}
For example,
Here, we have the data type int instead of void. This means that the function returns
an int value.
The code return (a + b); returns the sum of the two parameters as the function value.
The return statement denotes that the function has ended. Any code after return inside the
function is not executed.
Example 3: Add Two Numbers
// program to add two numbers using a function
#include <iostream>
// declaring a function
int add(int a, int b) {
return (a + b);
}
int main() {
int sum;
return 0;
}
Output
100 + 78 = 178
In the above program, the add() function is used to find the sum of two numbers.
We pass two int literals 100 and 78 while calling the function.
We store the returned value of the function in the variable sum, and then we print it.
Notice that sum is a variable of int type. This is because the return value of add() is
of int type.
Function Prototype
In C++, the code of function declaration should be before the function call. However, if we
want to define a function after the function call, we need to use the function prototype. For
example,
// function prototype
void add(int, int);
int main() {
// calling the function before declaration.
add(5, 3);
return 0;
}
// function definition
void add(int a, int b) {
cout << (a + b);
}
This provides the compiler with information about the function name and its parameters.
That's why we can use the code to call a function before the function has been defined.
The syntax of a function prototype is:
#include <iostream>
// function prototype
int add(int, int);
int main() {
int sum;
return 0;
}
// function definition
int add(int a, int b) {
return (a + b);
}
Run Code
Output
100 + 78 = 178
The above program is nearly identical to Example 3. The only difference is that here, the
function is defined after the function call.
That's why we have used a function prototype in this example.
int main() {
double number, squareRoot;
number = 25.0;
cout << "Square root of " << number << " = " << squareRoot;
return 0;
}
Output
Square root of 25 = 5
In this program, the sqrt() library function is used to calculate the square root of a number.
The function declaration of sqrt() is defined in the cmath header file. That's why we need to
use the code #include <cmath> to use the sqrt() function.
C++ Overloading (Function and Operator)
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
It is because these members have parameters only.
Types of overloading in C++ are:
o Function overloading
o Operator overloading
o Type Conversion:
Let's see a simple example.
#include<iostream>
using namespace std;
void fun(int);
void fun(float); void fun(int i)
{
std::cout << "Value of i is : " <<i<< std::endl;
}
void fun(float j)
{
std::cout << "Value of j is : " <<j<< std::endl;
}
int main()
{
fun(12);
fun(1.2);
return 0;
}
The above example shows an error "call of overloaded 'fun(double)' is ambiguous". The
fun(10) will call the first function. The fun(1.2) calls the second function according to our
prediction. But, this does not refer to any function as in C++, all the floating point constants
are treated as double not as a float. If we replace float to double, the program works.
Therefore, this is a type conversion from float to double.
o Function with Default Arguments
Let's see a simple example.
#include<iostream>
using namespace std;
void fun(int);
void fun(int,int);
void fun(int i)
{
std::cout << "Value of i is : " <<i<< std::endl;
}
void fun(int a,int b=9)
{
std::cout << "Value of a is : " <<a<< std::endl;
std::cout << "Value of b is : " <<b<< std::endl;
}
int main()
{
fun(12);
return 0;
}
The above example shows an error "call of overloaded 'fun(int)' is ambiguous". The fun(int a,
int b=9) can be called in two ways: first is by calling the function with one argument, i.e.,
fun(12) and another way is calling the function with two arguments, i.e., fun(4,5). The fun(int
i) function is invoked with one argument. Therefore, the compiler could not be able to select
among fun(int i) and fun(int a,int b=9).
o Function with pass by reference
Let's see a simple example.
#include <iostream>
using namespace std;
void fun(int);
void fun(int &);
int main()
{
int a=10;
fun(a); // error, which f()?
return 0;
}
void fun(int x)
{
std::cout << "Value of x is : " <<x<< std::endl;
}
void fun(int &b)
{
std::cout << "Value of b is : " <<b<< std::endl;
}
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 &).
Friend Function in C++
Introduction
In this tutorial, we will learn how to create a friend function in C++ with the help of some
examples.
Data hiding is a fundamental concept in object-oriented programming, and it restricts the
access of private members from outside the class.
What is a Friend Function in C++?
A friend function in C++ is defined as a function that can access private, protected and public
members of a class.
The friend function is declared using the friend keyword inside the body of the class.
Friend Function Syntax:
class className {
... .. ...
friend returnType functionName(arguments);
... .. ...
}
By using the keyword, the ‘friend’ compiler understands that the given function is a friend
function.
We declare friend function inside the body of a class, whose private and protective data needs
to be accessed, starting with the keyword friend to access the data. We use them when we
need to operate between two different classes at the same time.
What is Friend Function?
Friend functions of the class are granted permission to access private and protected
members of the class in C++. They are defined globally outside the class scope. Friend
functions are not member functions of the class. So, what exactly is the friend function?
A friend function in C++ is a function that is declared outside a class but is capable of
accessing the private and protected members of the class. There could be situations in
programming wherein we want two classes to share their members. These members may be
data members, class functions or function templates. In such cases, we make the desired
function, a friend to both these classes which will allow accessing private and protected data
of members of the class.
Generally, non-member functions cannot access the private members of a particular class.
Once declared as a friend function, the function is able to access the private and the protected
members of these classes.
Friend functions in C++ have the following types
Function with no argument and no return value
Function with no argument but with return value
Function with argument but no return value
Function with argument and return value
Declaration of friend function in C++
class class_name
{
friend data_type function_name(argument/s); // syntax of friend function.
};
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.