Professional Documents
Culture Documents
Unit IV
Unit IV
Templates
Templates are the foundation of generic programming, which involves writing code in a
way that is independent of any particular type. A template is a blueprint or formula for
creating a generic class or a function.
Syntax:
template <class T,…>
returntype funname(arg)
{
//body of template fun
}
Example:
#include<iostream>
using namespace std;
template<class T>
class swapping
{
public:
void swap(T &x,T &y)
{
T tt;
tt=x;
x=y;
y=tt;
}
};
int main()
{
int a=10,b=20;
float j=30,k=40;
cout<<"before swap"<<a<<b;
swap(a,b);
cout<<"after swap"<<a<<b;
cout<<"before swap"<<j<<k;
swap(j,k);
cout<<"after swap"<<j<<k;
return 0;
}
https://www.youtube.com/watch?v=8XTMa3GhZwg
Syntax
Example
#include<iostream>
using namespace std;
template <class T> //prefix code
class addition //template class
{
public:
T add (T,T);
};
template <class T>
T addition <T>:: add(T n1,T n2)
{
T result;
result=n1+n2;
return result;
}
int main()
{
addition <int>obj1;//object of class
addition<long>obj2;
int a=10,b=20,c;
long l=11,j=30,k;
c=obj1.add(a,b);
cout<<"int val"<<c;
k=obj2.add(l,j);
cout<<"long val"<<k;
return 0;
}
For example, consider the stack class. When it could only be used to store integer values. Even
though the underlying algorithms could be used to store any type of data, thehard-codingof the
data type into the stack class severely limited its application. However, by making stack into
a generic class, it can create a stack for any type of data.
Generic functions and classes provide a powerful tool that you can use to amplify your
programming efforts. Once you have written and debugged a template class, you have a solid
software component that you can use with confidence in a variety of different situations. You
are saved from the tedium of creating separate implementations for each data type with which
you want the class to work.
Template functions and classes are already becoming commonplace in programming. For
example, the STL (Standard Template Library) defined by C++ is, as its name implies, built
upon templates. although templates add a layer of abstraction, they still ultimately compile
down to the same, high-performance object code
#include<iostream>
using namespace std;
// Main Function
int main()
{
// instantiation with float and int type
Test <float, int> test1 (1.23, 123);
test1.show();
test2.show();
return 0;
}
Output:
1.23 and 123
100 and W
#include <iostream>
using namespace std;
template<class X,class Y>
void fun(X a,Y b)
{
std::cout << "Value of a is : " <<a<< std::endl;
std::cout << "Value of b is : " <<b<< std::endl;
}
int main()
{
fun(15,12.3); return 0;
}
/* Output : Value of a is : 15 Value of b is : 12.3 */
Example:
x/0;
Exception handling
It is conversion of system error message into user friendly error message. Exception is an
event which occurs during execution of the program which disrupts normal flow of a
program.
Exceptions provide a way to transfer control from one part of a program to another.
C++ exception handling is built upon three keywords: try, catch,and throw.
throw − A program throws an exception when a problem shows up. This is done using
a throw keyword.
catch − A program catches an exception with an exception handler at the place in a
program where you want to handle the problem. The catch keyword indicates the
catching of an exception.
try − A try block identifies a block of code for which particular exceptions will be
activated. It's followed by one or more catch blocks.
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
} catch( ExceptionName e1 ) {
// catch block
} catch( ExceptionName e2 ) {
// catch block
} catch( ExceptionName eN ) {
// catch block
}
Std Exceptions
Sr.No Exception & Description
1 std::exception
An exception and parent class of all the standard C++ exceptions.
2 std::bad_alloc
This can be thrown by new.
3 std::bad_cast
This can be thrown by dynamic_cast.
4 std::bad_exception
This is useful device to handle unexpected exceptions in a C++
program.
5 std::bad_typeid
This can be thrown by typeid.
6 std::logic_error
An exception that theoretically can be detected by reading the code.
7 std::domain_error
This is an exception thrown when a mathematically invalid domain
is used.
8 std::invalid_argument
This is thrown due to invalid arguments.
9 std::length_error
This is thrown when a too big std::string is created.
10 std::out_of_range
This can be thrown by the 'at' method, for example a std::vector and
std::bitset<>::operator[]().
11 std::runtime_error
An exception that theoretically cannot be detected by reading the
code.
12 std::overflow_error
This is thrown if a mathematical overflow occurs.
13 std::range_error
This is occurred when you try to store a value which is out of range.
14 std::underflow_error
This is thrown if a mathematical underflow occurs.
calculator()
{
x=y=result=0;
}
void getdata()
{
cout<<"\nEnter Two Numbers\n";
cin>>x>>y;
}
void addition()
{
result=x+y;
if(result>32000)
throw 'a';
else
cout<<"Addition ="<<result;
}
void substraction()
{
result=x-y;
if(result<0)
throw 'b';
else
cout<<"Subtraction ="<<result;
void multiplication()
{
result=x*y;
if(result>32000)
throw 'c';
else
cout<<"Product ="<<result;
}
void division()
{
if(y==0)
throw 'd';
else
{
result=x/y;
cout<<"Division ="<<result;
}
}
};
int main()
{
calculator cal;
int ch;
cout<<"1. Add\t2.Subtract\t3.Multiply\t4.Divide\n";
cout<<"\n Enter your choice\n";
cin>>ch;
try
{
switch(ch)
{
case 1:
cal.getdata();
cal.addition();
break;
case 2:
cal.getdata();
cal.substraction();
break;
case 3:
cal.getdata();
cal.multiplication();
break;
case 4:
cal.getdata();
cal.division();
break;
default:
cout<<"Wrong input";
}
}
catch(char c)
{
if (c=='a')
cout<<"Sum is too long! ";
else if(c=='b')
cout<<"Subtraction is a negative value! ";
else if(c=='c')
cout<<"Product is too long.! ";
else
cout<<"Division by zero!";
}
return 0;
}
Re throw
Re-throwing an exception in C++ involves using the throw statement without an argument
inside a catch block. When you use throw; without providing an exception object, it rethrows
the currently caught exception, allowing it to propagate up the call stack. This is useful when
you want to catch an exception, perform some handling or logging, and then let the exception
continue its journey up the call stack.
Rethrowing an exception in C++ involves catching an exception within a try block and
instead of dealing with it locally throwing it again to be caught by an outer catch block. By
doing this. we preserve the type and details of the exception ensuring that it can be handled
at the appropriate level within our program.
This approach becomes particularly valuable when managing exceptions at multiple levels
or when additional actions need to be performed before resolving the exception.
#include <iostream>
#include <stdexcept>
using namespace std;
int main()
{
try {
// Calculate the sum of 10 and the result of
// dividing 20 by 2
int result = calculateSum(10, divide(20, 2));
cout << "Result: " << result << endl;
return 0;
}
Output
Result: 20
Caught exception in divide(): Division by zero!
Caught exception in main: Division by zero!
Explanation:
The program first calculates the sum of 10 and the result of dividing 20 by 2, which is
20. This result is printed and there are no exceptions raised in this part.
Next, the program attempts to divide by zero when calculating the sum of 5 and the result
of dividing 10 by 0. This triggers a “Division by zero!” exception which is caught within
the divide() function and rethrown. The rethrown exception is then caught in the main()
function and is printed as “Division by zero!” along with the appropriate exception
handling messages.
Stack Unwinding
https://www.youtube.com/watch?v=AYQtEaf79ps
Stack Unwinding is the process of removing function entries from function call stack at run
time. The local objects are destroyed in reverse order in which they were constructed.
Stack Unwinding is generally related to Exception Handling. In C++, when an exception
occurs, the function call stack is linearly searched for the exception handler, and all the entries
before the function with exception handler are removed from the function call stack. So,
exception handling involves Stack Unwinding if an exception is not handled in the same
function (where it is thrown). Basically, Stack unwinding is a process of calling the
destructors (whenever an exception is thrown) for all the automatic objects constructed at run
time.
// Driver Code
int main()
{
f3();
getchar();
return 0;
}
Output
f3() Start
f2() Start
f1() Start
Caught Exception: 100
f3() End
When f1() throws exception, its entry is removed from the function call stack, because
f1() doesn’t contain exception handler for the thrown exception, then next entry in call
stack is looked for exception handler.
The next entry is f2(). Since f2() also doesn’t have a handler, its entry is also removed
from the function call stack.
The next entry in the function call stack is f3(). Since f3() contains an exception handler,
the catch block inside f3() is executed, and finally, the code after the catch block is
executed.
Note that the following lines inside f1() and f2() are not executed at all.
If there were some local class objects inside f1() and f2(), destructors for those local objects
would have been called in the Stack Unwinding process.