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

Notes_CSE2001_OOP_with_C++_Unit IV

The document covers Object Oriented Programming with C++ focusing on Exception Handling and Templates. It explains compile-time and run-time errors, the use of try-catch blocks for exception handling, and the creation of generic functions and classes using templates. Additionally, it introduces the Standard Template Library (STL) which provides a collection of template classes and functions for various data structures and algorithms.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Notes_CSE2001_OOP_with_C++_Unit IV

The document covers Object Oriented Programming with C++ focusing on Exception Handling and Templates. It explains compile-time and run-time errors, the use of try-catch blocks for exception handling, and the creation of generic functions and classes using templates. Additionally, it introduces the Standard Template Library (STL) which provides a collection of template classes and functions for various data structures and algorithms.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Class Notes: Object Oriented Programming with C++ (CSE2001)

UNIT – IV

Syllabus:

Exception handling and Templates:

Exception handling(user-defined exception) - Function template, Class template –


Template with inheritance , STL – Container, Algorithm, Iterator, vector, list, stack, map.

1. Exception handling:

Errors are the problems that occur in the program due to an illegal operation performed
by the user or by the fault of a programmer. Errors are also termed as bugs or faults.
There are mainly two types of errors in programming. Let us learn about both the
errors:

 Compile Time Errors are those errors that are caught during
compilation time. Some of the most common compile-time errors are
syntax errors, library references, incorrect import of library functions and
methods, uneven bracket pair(s), etc.
 Run-Time Errors are those errors that cannot be caught during
compilation time. As we cannot check these errors during compile time,
we name them Exceptions. Exceptions can cause some serious issues so
we should handle them effectively.

An exception is a problem that arises during the execution of a program. A C++


exception is a response to an exceptional circumstance that arises while a program is
running, such as an attempt to divide by zero. Another example is ‘file not found’ while
attempting to read the file in program.

Exception Handling is the process of handling exceptions such that the normal
execution of the system is not halted or program ends gracefully by giving proper error
message.

We use exception handling in C++ to separate the error handling code from the normal
code. For exception handling in C++, the try, catch, throw are used.

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
try-catch

Assuming a block will raise an exception, a method catches an exception using a


combination of the try and catch keywords. A try/catch block is placed around the code
that might generate an exception. Code within a try/catch block is referred to as
protected code, and the syntax for using try/catch as follows −

try {
// protected code (code might generate an exception.
} catch( ExceptionName e1 ) {
// catch block
} catch( ExceptionName e2 ) {
// catch block
} catch( ExceptionName eN ) {
// catch block
}

You can list down multiple catch statements to catch different type of exceptions in case
your try block raises more than one exception in different situations.

throw

Exceptions can be thrown from anywhere within a code block using throw statement
(keyword). The operand of the throw statement determines a type for the exception and
can be any expression and the type of the result of the expression determines the type
of exception thrown.

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


occurs −

double division(int a, int b) {


if( b == 0 ) {
throw "Division by zero condition!";
}
return (a/b);
}

Exception handling in C++ can throw both the basic data type as well as user-defined
objects as an exception. For throwing an exception in C++, we use the throw keyword.

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Catching Exceptions

The catch block following the try block catches any exception. You can specify what type
of exception you want to catch and this is determined by the exception declaration that
appears in parentheses following the keyword catch.

Refer programs except1.cpp, except2.cpp

using namespace std;


#include<iostream>
int main() {

try {
int age = 15;
if (age >= 18) {
cout << "Access granted - you are old enough.";
} else {
throw 505;
}
}
catch (int myNum) {
cout << "Access denied - You must be at least 18 years old.\n";
cout << "Error number: " << myNum;
}

cout<<"End program gracefully.";


}

//Exception example

#include <iostream>
using namespace std;

int main() {
int numerator, denominator;
float result;

cout << "Enter the numerator: ";


cin >> numerator;

cout << "Enter the denominator: ";


cin >> denominator;

try {
if (denominator == 0) {
throw "Division by zero error!";
}
result = static_cast<float>(numerator) / denominator;
cout << "Result of division: " << result << endl;
}
catch (const char* errorMessage) {
cerr << "Error: " << errorMessage << endl;
}

return 0;
}

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
2. Generic Functions

Generic functions are one of C++'s most useful features. They can be applied to all types of situations. As
mentioned earlier, whenever you have a function that defines a generalizable algorithm, you can make it
into a template function. Once you have done so, you may use it with any type of data without having to
recode it. Before moving on to generic classes, two examples of applying generic functions will be given.
They illustrate how easy it is to take advantage of this powerful C++ feature.

A generic function defines a general set of operations that will be applied to various types of data. The
type of data that the function will operate upon is passed to it as a parameter. Through a generic function,
a single general procedure can be applied to a wide range of data. As you probably know, many
algorithms are logically the same no matter what type of data is being operated upon.

For example, the Quicksort sorting algorithm is the same whether it is applied to an array of integers or
an array of floats. It is just that the type of the data being sorted is different. By creating a generic
function, you can define the nature of the algorithm, independent of any data. Once you have done this,
the compiler will automatically generate the correct code for the type of data that is actually used when
you execute the function. In essence, when you create a generic function you are creating a function that
can automatically overload itself.

Generics can be implemented in C++ using Templates.

A generic function is created using the keyword template. The normal meaning of the word
"template" accurately reflects its use in C++. It is used to create a template (or framework) that describes
what a function will do, leaving it to the compiler to fill in the details as needed. The general form of a
template function definition is shown here:
Defining a function template:

template <class Ttype> return-type functionName(parameter list)


{
// body of function
}

OR
template <typename T> T functionName (T parameter1, T parameter2, ...) {
// code
}

Here, Ttype is a placeholder name for a data type used by the function. This name may be used within the
function definition. However, it is only a placeholder that the compiler will automatically replace with an
actual data type when it creates a specific version of the function. Although the use of the keyword class
to specify a generic type in a template declaration is traditional, you may also use the keyword typename.

The following example creates a generic function that determines larger of two variables with which it is
called. Because the general process of finding larger of two values is independent of the type of the
variables, it is a good candidate for being made into a generic function.

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Features to remember:

 In addition to creating explicit, overloaded versions of a generic function, you can also
overload the template specification itself. To do so, simply create another version of the
template that differs from any others in its parameter list.
 You can mix standard parameters with generic type parameters in a template function.
 The generic function must perform the same general action for all versions—only
the type of data can differ.

3. Generic Classes

In addition to generic functions, you can also define a generic class. When you do this, you create a
class that defines all the algorithms used by that class; however, the actual type of the data being
manipulated will be specified as a parameter when objects of that class are created.

Generic classes are useful when a class uses logic that can be generalized. For example, the same
algorithms that maintain a queue of integers will also work for a queue of characters, and the same
mechanism that maintains a linked list of mailing addresses will also maintain a linked list of auto part
information. When you create a generic class, it can perform the operation you define, such as
maintaining a queue or a linked list, for any type of data. The compiler will automatically generate the
correct type of object, based upon the type you specify when the object is created.
The general form of a generic class declaration is shown here:

template <class Ttype> class Class-name {


.
..
}

Here, Ttype is the placeholder type name, which will be specified when a class is instantiated. If necessary,
you can define more than one generic data type using a comma-separated list.
Once you have created a generic class, you create a specific instance of that class using the following
general form:
Class-name <type> obj;

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Here, type is the type name of the data that the class will be operating upon. Member functions of a
generic class are themselves automatically generic. You need not use template to explicitly specify them
as such.

Example:
#include <iostream>
using namespace std;
template <class T>
class Calculator
{
private:
T num1, num2;

public:
Calculator(T n1, T n2)
{
num1 = n1;
num2 = n2;
}
void displayResult()
{
cout << "Numbers are: " << num1 << " and " << num2 << "." << endl;
cout << "Addition is: " << add() << endl;
cout << "Subtraction is: " << subtract() << endl;
cout << "Product is: " << multiply() << endl;
cout << "Division is: " << divide() << endl;
}

T add() { return num1 + num2; }

T subtract() { return num1 - num2; }

T multiply() { return num1 * num2; }

T divide() { return num1 / num2; }


};
//Main function body below

int main()
{
Calculator<int> intCalc(2, 1);
Calculator<float> floatCalc(2.4, 1.2);
cout << "Int results:" << endl;
intCalc.displayResult();
cout << endl << "Float results:" << endl;
floatCalc.displayResult();

return 0;
}

Example:

In the following program, the stack class is reworked into a generic class. Thus, it can be used to
store objects of any type. In this example, a character stack and a floating-point stack are created,
but any data type can be used.

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
// This function demonstrates a generic stack.
#include <iostream>
using namespace std;
const int SIZE = 10;
// Create a generic stack class
template <class StackType> class stack {
StackType stck[SIZE]; // holds the stack
int tos; // index of top-of-stack
public:
stack() {
tos = 0; // initialize stack
}
void push(StackType ob); // push object on stack
StackType pop(); // pop object from stack
};
// Push an object.
template <class StackType> void stack<StackType>::push(StackType ob) {
if(tos==SIZE) {
cout << "Stack is full.\n";
return;
}
stck[tos] = ob;
tos++;
}
// Pop an object.
template <class StackType> StackType stack<StackType>::pop() {
if(tos==0) {
cout << "Stack is empty.\n";
return 0; // return null on empty stack
}
tos--;
return stck[tos];
}

4. Template with inheritance: Left as an exercise

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
5. Standard Template Library (STL)
 The Standard Template Library or STL in C++ is a collection of template classes
and template functions that provide a generic way of programming.
 New feature added to C++ in recent years: the standard template library (STL).
 It provides general-purpose, templatized classes and functions that implement
many popular and commonly used algorithms and data structures, including, for
example, support for vectors, lists, queues, and stacks.
 STL is constructed from template classes, the algorithms and data structures can
be applied to nearly any type of data.
 STL is a large library, it is not possible to discuss all of its features here.
 At the core of the standard template library are three foundational items:
Containers, Algorithms, and iterators. These items work in conjunction with
one another to provide off-the-shelf solutions to a variety of programming
problems.

5.1 Container

Containers are objects that hold other objects, and there are several different
types. They are implemented as class templates, which allows a great flexibility
in the types supported as elements.

The containers manage storage space for its elements and provide member
functions to access them directly or through iterators.

There are 4 types of containers of STL in C++:

– Sequential: vector, deque, list, array, forward list


– Associative: set, multiset, map, multimap
– Adapters: stack, queue, priority queue.
– Unordered associative containers:

The diagram to represent types and examples are shown below:

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
You can also choose the most suitable C++ STL container that matches your needs. Different criteria used
for the selection are:

The functionality offered by the container.

The efficiency of some members. It is especially true for sequence containers, which offer complex trade-
offs between inserting/removing and accessing elements.

1. Sequence Containers: Sequence containers implement data structures that can be accessed
sequentially via their position. It preserves the insertion order of elements. These are internally
implemented as arrays or linked lists.

a. Array

Arrays are sequential homogeneous containers of fixed size. The elements are stored in contiguous
memory locations.

array<object_type, size> array_name;


b. Vector

Vectors are dynamic arrays, allowing the insertion and deletion of data from the end. They can grow or
shrink as required. Hence their size is not fixed, unlike arrays. In C++, vectors are like resizable arrays;
they store data of the same type in a sequence and their size can be changed during runtime as needed.

vector<object_type> vector_name;
//Program to demonstrate vector creation and input to vector
#include<iostream>
#include<vector>

using namespace std;

int main() {

const int N = 5;
vector<int> ivec(N);

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
for(int i =0; i<5;i++){
cin>>ivec[i];
}

for(int i=0; i<N; i++)


cout<<ivec[i]<<"\n";
}

//Program to demonstrate dynamic feature of vector


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

int main() {

vector<string> svec; //Declaration

string word;
while(word!="exit"){
cin>>word;
svec.push_back(word);
}
cout<<endl<<svec.size();
}

c. Deque

Deque is double-ended queue that allows inserting and deleting from both ends. They are more efficient
than vectors in case of insertion and deletion. Its size is also dynamic.

deque<object_type> deque_name;

d. List

The list is a sequence container that allows insertions and deletions from anywhere. It is a doubly linked
list. They allow non-contiguous memory allocation for the elements.

list<object_type> list_name;
e. Forward List

Forward Lists are introduced from C++ 11. They are implemented as singly linked list in STL in C++. It
uses less memory than lists and allows iteration in only a single direction.

forward_list<object_type> forward_list_name;

2. Associative Containers

Associative container is an ordered (sorted) container that provides a fast lookup of objects based on the
keys, unlike a sequence container which uses position. A value is stored corresponding to each key.

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
They are internally implemented as binary tree data structures. This results in logarithmic time
operations: O (log n).

a. Set

The set is used to store unique elements. The data is stored in a particular order (increasing order, by
default).

b. Map

The map contains elements in the form of unique key-value pairs. Each key can be associated with only
one value. It establishes a one-to-one mapping. The key-value pairs are inserted in increasing order of the
keys.

map<key_object_type, value_object_type> map_name;


Map Methods

In C++, the map class provides various methods to perform different operations on a map.

Operation Description
insert() adds an element (key-value pair) to the map
erase() removes an element or range of elements from the map
clear() removes all the elements from the map
find() searches the map for the given key
size() returns the number of elements in the map
empty() returns true if the map is empty
We can search for keys in a map using the find() function. Its syntax is: map_name.find(key);

Structure of Map, and use of erase() function

c. Multiset

Multiset is similar to a set but also allows duplicate values.

d. Multimap

Multimap is similar to a map but allows duplicate key-value pairs to be inserted. Ordering is again done
based on keys.

3. Unordered Associative Containers (introduced in C++11)

 Unordered Associative Container is an unsorted version of Associative Container.


 It is important to note that insertion order is not maintained. Elements are in random order.
 These are internally implemented as a hash table data structure. This results, on average, in
constant time operations -- O(1)

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
4. Container Adapters in C++

 STL in C++ also consists of a special type of container that adapts other sequence containers to
give a different interface with restricted functionality. Hence the name Container Adapters.
 The underlying container is encapsulated in such a way that its elements are accessed by the
members of the container adaptor independently of the underlying container class used.
 Unlike other containers, values are not directly initialized but with the help of other supported
methods.

a. Stack

A Stack is a container that provides Last-In-First-Out (LIFO) access. All the operations occur at the same
place called top of the stack. It is implemented on top of a deque by default.

stack<data_type> stack_name;

b. Queue

A queue is a container that provides First-In First-Out access. The insertion is done at the rear (back)
position and deletion at the front. It is implemented on top of a deque by default.

queue<data_type> queue_name;

c. Priority Queue

A priority Queue is similar to a queue, but every element has a priority value. This value decides what
element is present at the top, which is, by default, the greatest element in the case of STL in C++. This is
similar to the max heap data structure. It is implemented on top of the vector by default.

priority_queue<object_type> priority_queue_name;

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
5.2 C++ STL Iterators

Iterators are objects that are used to access elements of a container. We can declare an
iterator for each container in the C++ Standard Template Library. For example,

vector<int>::iterator it;

We often use iterator member functions like begin( ), end( ), etc. to return iterators that
point to container elements. For example,

vector<int> numbers = {3, 2, 5, 1, 4};


vector<int>::iterator itr1 = numbers.begin(); // returns an iterator
that points to the beginning of the numbers vector i.e. the element 3

cout << "First Element: " << *itr << " "<<endl; //returns 3

vector<int>::iterator itr2 = numbers.end();


// returns an iterator that points to the end of the numbers vector.

vector<int>::iterator itr2 = numbers.end() - 1;


// returns an iterator that points to the end of the numbers vector.
cout << "Last Element: " << *itr2; //prints 4

cout << itr1 << " "; // error, this is because, unlike pointers, we
cannot print an iterator.

Further readings: Iterator Categories and Operations Supported by Iterators


https://www.scaler.com/topics/stl-in-cpp/

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
5.3 Algorithms

 Algorithms in C++ STL define a collection of functions specially designed for use on a sequence of
objects.
 These are standalone template functions, unlike member functions of a container.
 There are approximately 60 algorithm functions that help save our time and effort.
 To use algorithms, you must include the <algorithm> header file.
 They also allow you to work with multiple container types simultaneously.
 Examples: The STL provides a range of algorithms, such as sort, find, and binary_search,
which can be used to manipulate data stored in containers.
 STL's algorithms in C++ are Non-Manipulative, Manipulative, Sorting, Set, and Relational
algorithms.

Containers Usability

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University
Tutorials: (Programs done in classroom)
1. Demonstrate the use of deque (STL).
Hint: Use the std::deque container to create a double-ended
queue and demonstrate operations like insertion at both ends,
access by index, and removal from both ends.
2. Demonstrate the use of vector (STL).
Hint: Use the std::vector container to create a dynamic array
and demonstrate operations like insertion at the end, access
by index, and resizing.
3. Problem: A user needs to maintain a list of tasks, with the
ability to add, remove, and mark tasks as complete. Solve
using STL (use suitable container).
Hint: Use std::vector or std::list to maintain the list of
tasks. Use push_back to add tasks, erase to remove tasks, and
a custom flag or struct member to mark tasks as complete.
4. A retail store needs to keep track of its inventory, including
the item name, quantity, and price. Utilize suitable container
to implement the functionality.
Hint: Use std::map or std::unordered_map to map item names to
a struct containing quantity and price. Use insert to add
items, and erase to remove items.
5. Use suitable container and algorithms to create the dictionary
demo and find the desired word.
Hint: Use std::unordered_map or std::map to store the
dictionary words and their meanings. Use algorithms like find
to search for a word and retrieve its meaning.

Experiments (programs) performed in Lab/Classroom are


already shared for reference.

Note: The document presents the notes on Module-IV of ‘OOP with C++’. The students has
to use the creativity to answer the questions asked in examination. The answers should be
accompanied with suitable examples, syntax and diagrams (as applicable).

Prepared by: Prof. Anand Motwani, Faculty, SCSE, VIT Bhopal University

You might also like