Template
Template
double theta,r;
public:
polar ()
theta=0;
r=0;
operator rectangular()
double x,y;
//float atheta=theta*pi/180;
x=r*cos(theta);
y=r*sin(theta);
return rectangular(x,y);
void output()
cout<<"\nr="<<r;
cout<<"\ntheta="<<theta;
};
rectangular r1,r2;
polar p1(3,45);
r1=p;// polar to rectangular conversion
r1.display();
}
Example:
/* Program to convert class Time to another class Minute.
#include <iostream.h>
#include <conio.h>
#include <iomanip.h>
class Time
{
int hrs,min;
public:
Time(int h,int m)
{
hrs=h;
min=m;
}
Time()
{
cout<<"\n Time's Object Created";
}
int getMinutes()
{
int tot_min = ( hrs * 60 ) + min ;
return tot_min;
}
void display()
{
cout<<"Hours: "<<hrs<<endl ;
cout<<" Minutes : "<<min <<endl ;
}
};
class Minute
{
int min;
public:
Minute()
{
min = 0;
t1.display();
m1.display();
getch();
}
This Pointer
If only one copy of each member function exists and is used by multiple objects, then for proper data members
accessing and updating, Compiler supplies an implicit pointer along with the functions names as this . this pointer is
an implicit parameter to all member functions. Therefore, inside a member function, this may be used to refer to the
invoking object. Friend functions do not have this pointer, because friends are not members of a class. Only member
functions have this pointer.
Following are the situations where this pointer is used:
1) When local variable’s name is same as member’s name
#include<iostream>
using namespace std;
int main()
{
Test obj;
int x = 20;
obj.setX(x);
obj.print();
return 0;
}
int main()
{
Test obj1(5, 5);
obj1.print();
return 0;
}
Method overriding
Function overriding is a feature that allows us to have a same function in child class which is already present
in the parent class. A child class inherits the data members and member functions of parent class, but when
you want to override a functionality in the child class then you can use function overriding. It is like creating
a new version of an old function, in the child class.
#include <iostream>
class BaseClass {
void disp()
{
cout<<"Function of Parent Class";
}
};
public:
Template
Templates are the foundation of generic programming, which involves writing code in a way that is
independent of any type.
A template is a blueprint or formula for creating a generic class or a function.
A template is one of the recently added feature in C++. It supports the generic data types and generic
programming.
Generic programming is an approach where generic data types are used as parameters in algorithms so that
they can work for a variety of suitable data types.
Example:
i. A class template for an array class would enable us to create arrays of various data types such as int
array and float array.
ii. A function template say mul() can be used for multiplying int, float and double type values.
A Template can be considered as Macro. When an object of specific type is defined for actual use, the
template definition for that class is substituted with the required data type.
Since a template is defined with a parameter that would be replaced by a specified data type at the time of
actual use of the class or function, the template is also called as parametrized class or functions.
Features of Template
i. Templates are easier to write. We can create only one generic version of our class or function instead
of manually creating specializations.
ii. Templates are easier to understand, since they provide a straightforward way of abstracting type
information.
iii. Templates are type safe. Because the types that templates act upon are known at compile time, the
compiler can perform type checking before errors occur.
Class Template
The general form of a generic class declaration is shown here:
template<classgeneric_data_type>
class class-name
{
…………………..
}
Disadvantage of Template
i. Many compilers historically have very poor support for templates, so the use of templates can make
code somewhat less portable.
ii. Almost all compilers produce confusing, unhelpful error messages when errors are detected in
template code. This can make templates difficult to develop
iii. Each use of a template may cause the compiler to generate extra code (an instantiation of the
template), so the indiscriminate use of templates can lead to code bloat,
resulting in excessively large executable.
Example:
1. WAP to demonstrate the concept of generic class.
#include<iostream>
using namespace std;
template<class T>
class Demo
{
private:
T x;
public:
Demo( T p)
{
x=p;
}
void show()
{
cout<<"\n"<<x;
}
};
int main()
{
Demo <char *>p1("Ram");
Demo <char> p2 ('A');
Demo <int> p3(5);
Demo <float>p4 (5.5);
p1.show ();
p2.show ();
p3.show ();
p4.show ();
2. WAP to find the area of circle using the concept of generic class.
#include <iostream>
using namespace std;
template<class T> // here T is generic data type
class Rectangle
{
private:
T len,bre;
public:
Rectangle(T l, T b)
{
len=l;
bre=b;
}
T area()
{
return(len*bre);
}
};
int main()
{
Rectangle<int>r1(4,5);
cout<<"Area= "<<r1.area()<<endl;
Rectangle <float>r2(4.5, 2.5);
cout<<"Area= "<<r2.area()<<endl;
}
In the above program, to define a class template Rectangle, we must prefix its definition by template<class
T>. This prefix tells the compiler that we are going to declare a template and use T as a type name in the class
definition. Thus, Rectangle has become parameterized class with T as its parameter. So, T can be substituted
by any data type like int, float or any user defined data type.
Here in the example the statement Rectangle<int>r1(4,5); initialize T as int type and hence the class
constructor receive integer type argument and method T area() also returns integer type value. Similarly, the
statement Rectangle <float>r2(4.5, 2.5); initialize T as float type and hence the class constructor receive
floating type argument and method T area() also returns Floating type value
#include <iostream>
using namespace std;
template<class T> // here T is generic data type
class Rectangle
{
private:
T len,bre;
3. WAP to find the sum of two complex number using the concept of generic class.
#include <iostream>
using namespace std;
template<class T>
class complex
{
T real;
T img;
public:
complex()
{
real=0;
img=0;
}
complex(T f1, T f2)
{
real=f1;
img=f2;
}
void show()
{
cout<<"Real= "<<real<<endl;
cout<<"Imaginary= "<<img<<endl;
}
};
int main()
{
//finding the sum of two integer complex number
4. WAP to find the sum of two complex number using the concept of generic class and operator overloading.
#include <iostream>
using namespace std;
template<class T>
class complex
{
T real;
T img;
public:
complex()
{
real=0;
img=0;
}
int main()
{
//finding the sum of two integer complex number
complex<int> c1(3,6);
complex<int> c2(2,-2);
complex<int> c3;//will invoke default constructor
c3=c1+c2; // equivalent to c3=c1.operator +(c2);
c3.show();
};
Example:
#include <iostream>
using namespace std;
template<class T1, class T2 >
class Demo
{
private:
T1 a;
T2 b;
public:
Demo(T1 x, T2 y)
{
a=x;
b=y;
}
void show()
{
cout<<"A= "<<a<<endl;
cout<<"B= "<<b<<endl;
}
};
int main()
{
Demo<int,float> d1(1,4.5);
d1.show();
Demo<char,int> d2('B',6);
d2.show();
2. WAP to declare a function template that can be used to swap two values of a given type of data.
//using concept of pointer
#include <iostream>
using namespace std;
template<class T >
void swap( T *fn, T *sn )
{
T tmp;
tmp=*fn;
*fn=*sn;
*sn=tmp;
}
int main()
{
int m=5,n=6;
cout<<"Before swapping"<<endl;
cout<<"M= "<<m<<endl<<"N= "<<n<<endl;
swap(&m,&n);
cout<<"After swapping"<<endl;
cout<<"M= "<<m<<endl<<"N= "<<n<<endl;
}
int main()
{
int m=5,n=6;
cout<<"Before swapping";
cout<<"M= "<<m<<endl<<"N= "<<n<<endl;
swap(m,n);
cout<<"After swapping";
cout<<"M= "<<m<<endl<<"N= "<<n<<endl;
}
3. Create a function template that can be used to find the maximum numbers among 10 numbers of given type of
data(int, float etc)
#include <iostream>
using namespace std;
template<class T >
T Max( T data[] )
{
T great=data[0];
for(inti=0;i<10;i++)
{
if(data[i]>great)
great=data[i];
}
return great;
}
int main()
{
int a[10]={4,3,7,9,8,5,88,34,23,11};
cout<<"Largest number= "<<Max(a)<<endl;
float b[10]={4.5,3.6,7.6,99.8,8,5,88.8,34.3,23.5,11.5};
cout<<"Largest number= "<<Max(b);
}
4. Create a function templates that can be used to find the minimum and maximum numbers among 10 numbers
of given type of data(int, float etc)
#include <iostream>
using namespace std;
template<class T >
T Max( T data[] )
{
T great=data[0];
for(inti=0;i<10;i++)
{
if(data[i]>great)
template<class T >
T Min( T data[] )
{
T small=data[0];
for(inti=0;i<10;i++)
{
if(data[i]<small)
small=data[i];
}
return small;
}
int main()
{
int a[10]={4,3,7,9,8,5,88,34,23,11};
cout<<"Largest number= "<<Max(a)<<endl;
cout<<"Smallest number= "<<Min(a)<<endl;
float b[10]={4.5,2.6,7.6,99.8,8,5,88.8,34.3,23.5,11.5};
cout<<"Largest number= "<<Max(b)<<endl;
cout<<"Smallest number= "<<Min(b)<<endl;
}
int main()
{
int m[10][10],n[10][10],row,col;
cout<<"Enter the number of rows and column"<<endl;
cin>>row>>col;
cout<<"Enter the elements of first matrix"<<endl;
for(inti=0;i<row;i++)
}
Example:
#include <iostream>
using namespace std;
template<class T1, class T2 >
void show(T1 x, T2 y)
{
cout<<"First Parameter= "<<x<<endl;
cout<<"Second Paramter= "<<y<<endl;
}
int main()
{
show(1,2);
show(1.4,3.5);
show('r',"Ram");
}
#include<iostream>
using namespace std;
template<class t>
void display(t x)
{
cout<<"From Template Function X= "<<x<<endl;
}
int main()
{
display(100);//will invoke template function with one argument as no exact matching ordinary function exist.
display(100.5f);// will invoke ordinary function as exact matching ordinary function exist
display(2.4f,3.5f);//will invoke ordinary function as exact matching ordinary function exist
display(3,5);//will invoke template function with two argument because non ordinary function matches this signature
}
Example 2:
#include<iostream>
using namespace std;
void display(float x)
{
cout<<"From Ordinary Function1 X= "<<x<<endl;
}
int main()
{
display(100); //will invoke ordinary function1 with one argument of type float(i.e. int casted to
float)
display("bhesh",5);
Runtime Error
When the code compiles without any error, there is still chance that the code will fail at run time. The errors only
occur at run time are call run time errors. Run time errors are those that passed compiler’s checking, but fail when the
code gets executed. These errors are unchecked.
The following are some common runtime errors:
Divide by zero exception
Array index out or range exception
StackOverflow exception
Dereferencing of an invalid pointer
etc……….
So, runtime errors are those which are generally can’t be handled and usually refers catastrophic failure.
Exception
An exception is a run-time error. Proper handling of exceptions is an importantprogramming issue. This is because
exceptions can and do happen in practice andprograms are generally expected to behave gracefully in face of such
exceptions.
Unless an exception is properly handled, it is likely to result in abnormal programtermination and potential loss of
work. For example, an undetected division by zeroor dereferencing of an invalid pointer will almost certainly
terminate the programabruptly.
Types
1. Synchronous: Exception that are caused by events that can be control of program is called synchronous
exception. Example, array index out or range exception.
2. Asynchronous: Exception that are caused by events beyond the control of program is called synchronous
exception. Example, Exception generated by hardware malfunction.
The purpose/Use of exception handling mechanism is to provide means to detect and report an exception so that
appropriate actions can be taken. Exception handling mechanism in C++ consists of four things:
i. Detecting of a run-time error (Hit the exception)
ii. Raising an exception in response to the error (Throw the exception)
iii. Receive the exception information (Catch the exception)
iv. Taking corrective action. (Handle the exception)
C++ provides a language facility for the uniform handling of exceptions. Underthis scheme, a section of code whose
execution may lead to run-time errors islabeled as a try block. Any fragment of code activated during the execution of
atry block can raise an exception using a throw clause. All exceptions are typed(i.e., each exception is denoted by an
object of a specific type). A try block isfollowed by one or more catch clauses. Each catch clause is responsible for
thehandling of exceptions of a particular type.When an exception is raised, its type is compared against the catch
clausesfollowing it. If a matching clause is found, then its handler is executed. Otherwise,the exception is propagated
up, to an immediately enclosing try block (if any). Theprocess is repeated until either the exception is handled by a
matching catch clauseor it is handled by a default handler.
The general form is as below:
……….
……….
try
{
…..
…..
throw exception; //block of statements which detect and throws an exception
}
catch(type arg) //catches exception
{
…..
…. //block of statements that handle the exception
…..
}
…….
…….
Example:
WAP to input two number and divide first number by second. The program must handle the divide by zero exception.
So, in the above program, when no exception is thrown, the catch block is skipped and outputs correct result. But
when the user input zero for denominator, the exception is thrown using throw statement with int type object as
argument. Since the exception object type is int, the exception handler i.e. catch statement containing int type
argument catches the exception and handles it by displaying necessary message or performing necessary steps further.
Note:
i. During execution, when throw statement is encountered, then it immediately transfers the control suitable
exception handler i.e. catch block. Hence all the statement after throw in try block are skipped.
ii. If there are multiple catch block with integer type argument, then the first one immediately after try block
gets executed.
iii. When an exception object is thrown and non of the catch block matches, the program is aborted with the
help of abort() function which is invoked automatically.
Example:
#include<iostream>
using namespace std;
int divide(int,int);
int main()
{
intnu,de,res;
cout<<"Enter numerator and denominator";
cin>>nu>>de;
try
{
res=divide(nu,de);
cout<<"Result= "<<res;
}
Example:
WAP to input two numbers and divide first number by second. The result must be stored in the index entered by user.
#include<iostream>
using namespace std;
int divide(int,int);
int main()
{
}
catch(typeNarg)
{
Example:
#include<iostream>
using namespace std;
int divide(int,int);
int main()
{
try
{
doublenu,de,res[10],c;
intind;
cout<<"Enter numerator and denominator"<<endl;
cin>>nu>>de;
if(de==0)
{
throw(de);
}
cout<<"Enter the index to store the result"<<endl;
cin>>ind;
if(ind>=10)
{
throw(ind);
}
c=nu/de;
res[ind]=c;
cout<<"Result= "<<c<<" Successfully stored at "<<ind<<" posiion";
}
catch(int a)
{
cout<<"Index out or range exception: Index= "<<a;
}
catch(double d)
{
cout<<"Divide by zero exception: Denominator= "<<d;
}
}
Algorithms
The header algorithm defines a collection of functions especially designed to be used on ranges of elements.They act
on containers and provide means for various operations for the contents of the containers.
Algorithm
Sorting
Searching
Important STL Algorithms
Useful Array algorithms
Partition Operations
Containers
Containers or container classes store objects and data. There are in total seven standard “first-class” container
classes and three container adaptor classes and only seven header files that provide access to these containers or
container adaptors.
Sequence Containers: implement data structures which can be accessed in a sequential manner.
vector
list
deque
arrays
forward_list
Container Adaptors : provide a different interface for sequential containers.
queue
priority_queue
stack
Associative Containers : implement sorted data structures that can be quickly searched
set
multiset
map
multimap
Iterators
As the name suggests, iterators are used for working upon a sequence of values. They are the major feature that allow
generality in STL.
Programming in small
Programming in the small characterizes projects with the following attributes:
• Code is developed by a single programmer, or perhaps by a very small collection of
programmers. A single individual can understand all aspects of a project, from top to bottom,
beginning to end.
• The major problem in the software development process is the design and development of
algorithms for dealing with the problem at hand.
Programming in large
Programming in the large characterizes software projects with features such as the following:
• The software system is developed by a large team, often consisting of people with many different
skills. No single individual can be considered responsible for the entire project, or even
necessarily understands all aspects of the project.
• With programming in the large, coding managers place emphasis on partitioning work
into modules with precisely-specified interactions. This requires careful planning and careful
documentation.
• The major problem in the software development process is the management of details and the
communication of information between diverse portions of the project.
Classname
Responsibilities Collaborators
Greeter
Display informative initial message Database manager
Offer user choice of options Recipe manager
Pass control to either
• Recipe database manager
• Plan manager for processing
Card reader
Tell ATM when card is inserted ATM
Read information from card Card
Eject card
Retain card
Cash dispenser
Keep track of cash on hand, starting with Log
initial amount
Report whether enough cash is available
Dispense cash
Advantages
Sequence Diagram
Software components
• In programming and engineering disciplines, a component is an identifiable part of a larger
program or construction. Usually, a component provides a particular function or group of related
functions. In programming design, a system is divided into components that in turn are made up
of modules. Component test means testing all related modules that form a component as a group
to make sure they work together.
i) Behavior and State: One way to view a component is as a pair consisting of behaviour and state:
• The behavior of a component is the set of actions it can perform. The complete description of all
the behavior for a component is sometimes called the protocol. For the Recipe component this
includes activities such as editing the preparation instructions, displaying the recipe on a terminal
screen, or printing a copy of the recipe.
• The state of a component represents all the information held within it at a given point of time. For
our Recipe component the state includes the ingredients and preparation instructions. Notice that
the state is not static and can change over time. For example, by editing a recipe (a behavior) the
user can make changes to the preparation instructions (part of the state).
ii) Coupling and Cohesion
• Two important concepts in the design of software components are coupling and cohesion.
Cohesion is the degree to which the responsibilities of a single component form a meaningful
unit. High cohesion is achieved by associating in a single component tasks that are related in
some manner. Probably the most frequent way in which tasks are related is through the necessity
to access a common data value. This is the overriding theme that joins, for example, the various
responsibilities of the Recipe component.
• Coupling, on the other hand, describes the relationship between software components. In general,
it is desirable to reduce the amount of coupling as much as possible, since connections between
software components inhibit ease of development, modification, or reuse
iii) Interface and Implementation
It is very important to know the difference between interface and implementation. For example,
when a driver drives the car, he uses the steering to turn the car. The purpose of the steering is
known very well to the driver, but the driver need not to know the internal mechanisms of
different joints and links of various components connected to the steering.
An interface is the user’s view of what can be done with an entity. It tells the user what can be
performed. Implementation takes care of the internal operations of an interface that need not be
known to
the user. The implementation concentrates on how an entity works internally. Their comparison is
shown in Table
• The first step in this process is to formalize the patterns and channels of communication.
• A decision should be made as to the general structure that will be used to implement each
component. A component with only one behavior and no internal state may be made into a
function. Components with many tasks are probably more easily implemented as classes. Names
are given to each of the responsibilities identified on the CRC card for each component, and these
will eventually be mapped onto method names. Along with the names, the types of any arguments
to be passed to the function are identified.
• Next, the information maintained within the component itself should be described. All
information must be accounted for. If a component requires some data to perform a specific task,
the source of the data, either through argument or global value, or maintained internally by the
component, must be clearly identified.
• Names should be internally consistent, meaningful, preferably short, and evocative in the context
of the problem.
• Use pronounceable names. As a rule of thumb, if you cannot read a name out loud, it is not a good
one.
• Use capitalization (or underscores) to mark the beginning of a new word within a name, such as
“CardReader” or “Card reader”, rather than the less readable “cardreader”.
• Examine abbreviations carefully. An abbreviation that is clear to one person may be confusing to
the next. Is a “TermProcess" a terminal process, something that terminates processes, or a process
associated with a terminal?
• Avoid names with several interpretations.
The task now is to transform the description of a component into a software system
implementation major portion of this process is designing the data structures that will be used by
each subsystem to maintain the state information required to fulfil the assigned responsibilities
It is here that the classic data structures of computer science come into play. The selection of data
structures is an important task, central to the software design process. Once they have been
chosen, the code used by a component in the fulfilment of a responsibility is often almost self-
It is also at this point that descriptions of behavior must be transformed into algorithms. These
descriptions should then be matched against the expectations of each component listed as a
collaborator, to ensure that expectations are fullled and necessary data items are available to carry
out each process.
Implementation of components
• The next step is to implement each component's desired behavior. If the previous steps were
correctly addressed, each responsibility or behavior will be characterized by a short description.
The task at this step is to implement the desired activities in a computer language.
• An important part of analysis and coding at this point is characterizing and documenting the
necessary preconditions a software component requires to complete a task, and verifying that the
software component will perform correctly when presented with legal input values.
Integration of components
• Once software subsystems have been individually designed and tested, they can be integrated into
the final product. This is often not a single step, but part of a larger process. Starting from a
simple base, elements are slowly added to the system and tested, using stubs: simple dummy
routines with no behavior or with very limited behavior: for the as yet unimplemented parts.
• Testing of an individual component is often referred to as unit testing.
• Integration testing can be performed until it appears that the system is working as desired.
• Re-executing previously developed test cases following a change to a software component is
sometimes referred to as regression testing.
• Give example of car making with different components bumper, gear, engine etc.