object oriented programming using c++ part iii
TRANSCRIPT
OOP/AKN/Part_III/1
Object Oriented Programming
Using C++
Part III
Ajit K Nayak, Ph.D.
SOA University
OOP/AKN/Part_III/3
Classification/Inheritance
Animal
Mammal Bird
man woman
John Mary
People Dog . . . . .
Classification
Inheritance
OOP/AKN/Part_III/4
Classification
Classification arises from the universal need to
describe uniformities among different
instances.
Classification is a basic idea for understanding
the concept inheritance
OOP/AKN/Part_III/5
Sharing
The sharing of information is important in object-
orientation.
Inheritance is the technique to realize sharing of
information without explicit redefinition.
Inheritance means that new classes can be derived
from existing classes .
The subclass inherits the attributes and the
operations of the superclass (base class) but the
subclass (derived class) can define additional
operations and attributes.
OOP/AKN/Part_III/6
Sharing (contd.)
This mechanism is also known as
specialization mechanism.
Instances of a subclass are specializations
(additional state and behavior) of the instances
of the superclass.
This mechanism can also be considered as
generalization mechanism.
Instances of the superclass generalize (restrict)
the instances of the subclasses.
OOP/AKN/Part_III/7
Inheritance
The Purpose
1. Reusing the existing design reduces
software development and testing costs.
2. A new class obtains the data members
and member functions of an existing
class.
OOP/AKN/Part_III/8
What is Inheritance? “A inherits from B”.
Objects of class A thus also have attributes and
methods of class B without the need to redefine
them along with its own defined attributes and
methods.
Objects of a subclass(A) can be used where
objects of the corresponding superclass (B) are
expected.
This is due to the fact that objects of the
subclass share the same behavior as objects of
the superclass.
OOP/AKN/Part_III/10
Example
Employee
name
number
getData()
printData()Scientist
publication
getData()
printData()
Manager
title
clubDues
getData()
printData()
OOP/AKN/Part_III/11
Example (contd.)class Employee{
char name[20];
int number;
public:
void getData(){
cin>>name;cin>>number;
}
void printData(){
cout<<name<<number<<endl;
}
};
OOP/AKN/Part_III/12
Example (contd.)class Manager:public Employee{
char title[10];
double dues;
public:
void getData(){
cin>>name;cin>>number;getData();Employee::getData();
cin>>title; cin>>dues;
}
void printData(){
Employee::printData();
cout<<title<<dues<<endl;
} };
OOP/AKN/Part_III/13
Example (contd.)class Scientist:public Employee{
int pub;
public:
void getData(){
Employee::getData();
cin>>pub;
}
void printData(){
Employee::printData();
cout<<pub<<endl;
}
};
OOP/AKN/Part_III/14
Example (contd.)main(){
Employee e1;
Manager m1;
Scientist s1;
e1.getData(); e1.printData();
m1.getData(); m1.printData();
s1.getData(); s1.printData();
}
OOP/AKN/Part_III/15
Example (revisited)class Employee{
protected:
char name[20]; int number;
public: . . .
};
class Manager:public Employee{
char title[10]; double dues;
public: void getData(){
cin>>name; cin>>number;
cin>>title; cin>>dues;
}
. . .};
OOP/AKN/Part_III/16
ObservationsPublic Inheritance
When a subclass is derived from a base class, all
the members of base are inherited to the sub-
class
The public and protected members of Base
become public and protected members
respectively in sub class. The private members of
Base remains as hidden members in the sub
class (derived class)
OOP/AKN/Part_III/17
Example (revisited)class Employee{
char name[20];
int number;
public:
void getData();
void print(){
cout<<name<<number<<endl;
}
};
OOP/AKN/Part_III/18
Example (contd.)class Scientist:public Employee{
int pub;
public:
void getData();
void printData(){
Employee::print();
cout<<pub<<endl;
}
};
OOP/AKN/Part_III/19
Example (contd.)main(){
Employee e1;
Scientist s1;
e1.getData();
e1.print();
s1.getData();
s1.print();
s1.printData();
}
OOP/AKN/Part_III/20
Naming Conflicts If attributes or methods defined in a subclass have the
same name as attributes or methods defined in the
super class then a technique called „overriding’ is
used to solve the conflict.
The function in the derived class with the same function (or variable) name will override the functions (or variables) in the base classes.
But it can still invoke or get the override functions(variables) with scope resolution operator (::).
When a base class member function is overridden in a derived class, it is common to invoke the base class version and some extra work is done.
OOP/AKN/Part_III/21
Example
Employee
fstName: char*
lstName :char*
Constructor ()
Destructor ()
print ()
HrlyWorker
wage: double
hours: double
Constructor
getPay()
print()
OOP/AKN/Part_III/22
Example (Overriding)class Employee{
public:
Employee(char*, char*);
void print(void);
~Employee();
private:
char* fstName;
char* lstName;
};
OOP/AKN/Part_III/23
Example (contd.)Employee::Employee(char* fst,char* lst){
fstName=new char[strlen(fst)+1];
strcpy(fstName, fst);
lstName=new char[strlen(lst)+1];
strcpy(lstName, lst);
}
void Employee::print(void){
cout<<fstName<<„ „<<lstName<<endl;
}
Employee::~Employee(){
delete []fstName; delete[]lstName;
}
OOP/AKN/Part_III/24
Example (contd.)class HrlyWorker:public Employee{
public:
Hrlyworker(char*, char*,double, double);
double getPay();
void print(void);
private:
double wage;
double hours;
};
OOP/AKN/Part_III/25
Example (contd.)HrlyWorker:: HrlyWorker(char* fst,char*
lst, double hrs, double wg):
Employee(fst,lst){
hours=hrs;
wage=wg;
}
void HrlyWorker::print(){
Employee::print(); // Base class version
cout<<getPay()<<endl; // Extra task
}
OOP/AKN/Part_III/26
Example(contd.)
double HrlyWorker::getPay(){
return wage*hours;
}
main(){
HrlyWorker h(“Bob”, “smith”,
40.0, 10.0);
h.print();
}
OOP/AKN/Part_III/27
Observations A derived class can override a base-class member
function by supplying a new version of that function
with same arguments.
Not using the scope resolution operator to reference
the overridden base class member function will
cause in infinite recursion.
If the derived class needs a constructor and base
class has a constructor, then that constructor must
be called.
If that constructor needs arguments, then such
arguments must be provided.
OOP/AKN/Part_III/28
Observations A derived class constructor can specify
initializers for its own members and its immediate bases only.
A derive class cannot directly initialize members of a base but it can do so via the constructor of base only
Class members are constructed top-bottom of the hierarchy. i.e. first the base class member, and then the derived class member
They are destroyed in opposite order.
OOP/AKN/Part_III/30
Example class Point{
protected: int xCo; int yCo;
public:
Point(int, int);
~Point(); };
class Circle:public Point{
double radius;
public:
Circle(double,int, int);
~Circle(); };
OOP/AKN/Part_III/31
Example(contd.)Point::Point(int a, int b)
:xCo(a),yCo(b){
cout<<“Point constructor:”<<endl;}
Point::~Point(){
cout<<“Point destructor:”<<endl;}
Circle::Circle(double r, int a, int b)
:Point(a,b),radius(r){
cout<<“Circle constructor:”<<endl; }
Circle::~Circle(){
cout<<“Circle Destructor:”<<endl; }
OOP/AKN/Part_III/32
Example(contd.)main(){
{
Point p(11,22);
}
{
Circle cl1(4.5,72,29);
}
Circle cl2(10.0,72,29);
Circle cl3(23.7, 0,0);
}
OOP/AKN/Part_III/33
Categories of InheritanceSingle(Simple) inheritance:
A class inherits from only one super
class.
It can again be of two types
1. Single Level 2. Multi Level
Employee
Manager
Point
Circle
Single level
Point
Circle
Cylinder
Multi level
OOP/AKN/Part_III/34
Categories of Inheritance contd.Multiple inheritance:
When a class is derived from more than one base
class, it is called the multiple inheritance
It means that a derived class inherits the members
of several base classes.
Animal
Bat
Bird
OOP/AKN/Part_III/35
Exp: Multi Level Inheritance
Student
Roll
getRoll()
PrintRoll()
Test
Mark1
Mark2
getMark()
PrintMark()
Result
Total
displayMark()
OOP/AKN/Part_III/36
Example multi level Inheritanceclass Student{
protected:
int roll;
public:
void getRoll(int a){roll=a;}
void printRoll(void){
cout<<“Roll:”<<roll<<endl;
}
};
OOP/AKN/Part_III/37
Example (Contd.)class Test:public Student{
protected:
float mark1;
float mark2;
public:
void getMark(float a, float b){
mark1=a; mark2=b;}
void printMark(){printRoll();
cout<<“Sub1:”<<mark1<<endl;
cout<<“Sub2:”<<mark2<<endl;
} };
OOP/AKN/Part_III/38
Example (Contd.)class Result:public Test{
public:
void displayMark(){
printMark();
total=mark1+mark2;
}
private:
float total;
};
OOP/AKN/Part_III/39
Example (Contd.)main(){
Result s1;
s1.getRoll(102);
s1.getMark(75.0,30.0);
s1.displayMark();
}
OOP/AKN/Part_III/40
Different types of Inheritance
mechanism
A derived class may be inherited as public,
protected, or private
It defines the visibility mode of base class
members inside derived class.
Exp: B is inherited from A, then you can write
class B: public A or
class B: protected A or
class B: private A or
Public derivation
Protected inheritance
Derived privately
OOP/AKN/Part_III/41
Inheritance mechanisms
Inheritance
Type
Base class member access Specifier
Public Protected Private
Public Public in d.
class
Protected
in d. class
Hidden in
d. class
Protected Protected in
d. class
Protected
in d. class
Hidden in
d. class
Private Private in
d.class
Private in d.
class
Hidden in
d. class
OOP/AKN/Part_III/42
Exp: Multiple Inheritance
It is used when Type A is a kind of Type B and
Type C and Type …
The properties and behaviours of all the
parents (base classes) are inherited to the
child(derived class).
OOP/AKN/Part_III/43
An Example
Base1
value
getData( )
Base2
letter
getData( )
Derived
real
getData( )
OOP/AKN/Part_III/44
Example (contd.)class Base1{
public:
Base1(int x):value(x){}
int getData()
{
return value;
}
protected:
int value;
};
OOP/AKN/Part_III/45
Example (contd.)class Base2{
public:
Base2(char c):letter(c){}
char getData()
{
return letter;
}
protected:
char letter;
};
OOP/AKN/Part_III/46
Example (contd.)class Derived:public Base1,public
Base2{
public:
Derived(int i,char c, double f):
Base1(i),Base2(c),real(f){}
double getData()
{
return real;
}
private:
double real;
};
OOP/AKN/Part_III/47
Example (contd.)main(){
Base1 b1(10);
Base2 b2(„z‟);
Derived d(7,‟A‟,3.5);
cout<<b1.getData(); //?
cout<<b2.getData(); //?
cout<<d.getData(); //?
}
OOP/AKN/Part_III/48
Example with pointers to objectsmain(){
Base1 b1(10), *b1Ptr;
Base2 b2(„z‟), *b2ptr;
Derived d(7,‟A‟,3.5);
b1Ptr=&d; cout<<b1Ptr->getData();//?
b2Ptr=&d; cout<<b2Ptr->getData();//?
}
OOP/AKN/Part_III/49
Observations1. An object of a publicly derived class can also be
treated as an object of its base class.
2. But using a base class object as a derived class
object may cause an error.
3. It is always valid to assign a derived class pointer to
a base class pointer because derived class object is
also a base class object but…
4. The base class pointer can only visualize the base
class part of the derived class object
5. This is also called “object slicing” i.e. only the base part
(small) of the derived object (bigger) is visible and another
part is not visible to the base pointer
OOP/AKN/Part_III/50
Observations contd.6. In other words the derived object (a big object) is
sliced to become a base object (a small object).
7. The Compiler in above case performs an implicit conversion of the derived class pointer to a base class pointer
6. It is also allowed to assign a base class pointer to a derived class pointer but..
7. Assigning a base class pointer directly to a derived class pointer is an inherently dangerousassignment!!!
8. In this case compiler does not perform an implicit conversion.
OOP/AKN/Part_III/51
Exampleclass Point{
protected:
int xCo;
int yCo;
public:
Point():xCo(0),yCo(0){}
Point(int a,int b):
xCo(a),yCo(b){}
friend ostream& operator <<
(ostream&,Point&);
};
OOP/AKN/Part_III/52
Exampleclass Circle:public Point{
protected:
double radius;
public:
Circle(double r, int a, int b):
Point(a,b),radius(r){}
void area();
friend ostream& operator <<
(ostream&,Circle&);
};
OOP/AKN/Part_III/53
Example (contd.)main(){
Point *pPtr=NULL, p(30,50);
Circle *cPtr=NULL, c(2.7,10,5);
cout<<p;
cout<<c;
/* these are ok */
pPtr=&c;
cout<<*pPtr;
// valid(2)
//sees only base part(3)/* Treats circle as a point, it can
see the base part only */
OOP/AKN/Part_III/54
Example (Contd.)cPtr=(Circle *)pPtr;
cout<<*cPtr;
cout<<cPtr->area();
/* casts base class pointer to derived
class pointer ok*/
pPtr=&P;
cPtr=(Circle *)pPtr; cout<<*cPtr;
cout<<cPtr->area();
/* Dangerous: Treating Point as a circle */
}
OOP/AKN/Part_III/55
Exp: Multi Level Inheritance
Student
Roll
getRoll()
PrintRoll()
Test
Mark1
Mark2
getMark()
PrintMark()
Result
Total
displayMark()
OOP/AKN/Part_III/56
Example multi level Inheritanceclass Student{
protected:
int roll;
public:
void getRoll(int a){roll=a;}
void printRoll(void){
cout<<“Roll:”<<roll<<endl;
}
};
OOP/AKN/Part_III/57
Example (Contd.)class Test:public Student{
protected:
float mark1;
float mark2;
public:
void getMark(float a, float b){
mark1=a; mark2=b;}
void printMark(){printRoll();
cout<<“Sub1:”<<mark1<<endl;
cout<<“Sub2:”<<mark2<<endl;
} };
OOP/AKN/Part_III/58
Example (Contd.)class Result:public Test{
public:
void displayMark(){
printMark();
total=mark1+mark2;
}
private:
float total;
};
OOP/AKN/Part_III/59
Example (Contd.)main(){
Result s1;
s1.getRoll(102);
s1.getMark(75.0,30.0);
s1.displayMark();
}
OOP/AKN/Part_III/62
Example: codeclass Base{
public:
void show(void){cout<<“Base”;}
};
class Derv1:public Base{...
public:
void show(void){cout<<“Derv1”;}
};
class Derv2:public Base{...
public:
void show(void){cout<<“Derv2”;}
};
OOP/AKN/Part_III/63
Example (Contd.)main(){
Base b, *ptr;
Derv1 dv1; Derv2 dv2;
ptr=&b; ptr->show();
ptr=&dv1; ptr->show();
ptr=&dv2; ptr->show();
}
//Base1
//Base1
//Base1
It is becauseThe compiler ignores the contents of the pointer ptr and chooses the member function that matches the type pointer. (object slicing, static binding…)Is it possible to get Derv1 and Derv2 for 2nd and third prints?Late binding helps to achieve this
OOP/AKN/Part_III/64
Example (Contd.)Modify Base class of the above program as
follows
class Base{
public:
virtual void show(){
cout<<“Base”;
}
};
Now the outputs will be Derv1 and Derv2
respectively.
OOP/AKN/Part_III/65
Virtual Functions If a function is declared as “virtual” in the base class
then the implementation will not be decided at
compile time but at the run time.
This principle is called the late binding
Once a function is declared virtual, it remains virtual
all the way down the inheritance hierarchy from that
point, even if it is not declared virtual explicitly when
a derived class overrides it
But for the program clarity declare these functions as
virtual explicitly at every level of hierarchy
OOP/AKN/Part_III/66
Virtual Functions (contd.)
ptr=&dv1
ptr=&dv2
Non Virtual pointer access
Base::show()
Derv1::show()
Derv2::show()
Virtual pointer access
ptr=&dv1
ptr=&dv2
Ptr->show()
Ptr->show()
Early Binding
Late Binding
OOP/AKN/Part_III/67
Pure Virtual Function It is a virtual function having no body
syntax: virtual void show()=0;
But this function can‟t be removed from the
function body.(compiler error)
It is because the base class pointer is
allowed to refer the base class members
only.
Pure virtual functions may be inherited /
overridden in derived classes.
OOP/AKN/Part_III/68
Abstract vs Concrete class
A class never used for instantiation is called an
abstract class.
The sole purpose of an abstract class is to
provide an appropriate base class for derivation
of sub classes.
A class will be treated as an abstract base
class if at least one member function of the
class is purely virtual
Attempting to instantiate an object of an
abstract is a syntax error
OOP/AKN/Part_III/69
Abstract class (contd.)
If a class is derived from a class with a pure
virtual function and if no definition for that
function is supplied in the derived class then
That virtual function also remains purely virtual in
the derived class.
The consequence is that the derived class again
becomes an abstract class
i.e. It is not possible now to instantiate the derived
class also!!!
OOP/AKN/Part_III/71
Exampleclass Shape {
protected:
int width, height;
public:
Shape( int a, int):
width(a),height(b){}
virtual int area()=0;
};
OOP/AKN/Part_III/72
Exampleclass Rectangle: public Shape{
public:
Rectangle( int a, int b):
Shape(a, b) { }
int area () {
cout << "Rectangle area :";
return (width * height);
}
};
OOP/AKN/Part_III/73
Exampleclass Triangle: public Shape{
public:
Triangle( int a, int b):
Shape(a, b) { }
int area () {
cout << "Triangle area :";
return (width * height / 2);
}
};
OOP/AKN/Part_III/74
Examplemain( ) {
Shape *shptr;
Rectangle rec(10,7);
Triangle tri(10,5);
shptr = &rec;
cout<<shptr ->area();
shptr = &tri;
cout<<shptr ->area();
}
OOP/AKN/Part_III/75
Example Employee
Name
Earnings()
Print()
HourlyWorker
Wage, hours
Earnings()
Print()
CommissionWorker
Salary, Commission & quantity
Earnings()
Print()
PieceWorker
Wage per piece & quantity
Earnings()
Print()
OOP/AKN/Part_III/76
Exampleclass Employee{
public:
Employee(char *);
~Employee();
virtual double earnings()=0;
virtual void print();
protected:
char *name;
};
OOP/AKN/Part_III/77
Example (Contd.)main(){
Employee *e;
CommissionWorker c("Lee",200.0,3.0,15);
e=&c;
e->print(); e->earnings();
PieceWorker p("Margaret",2.5,200);
e = &p;
e->print(); e->earnings();
HrlyWorker h("Sue",2.5,200);
e = &h;
e->print(); e->earnings(); }
OOP/AKN/Part_III/78
Polymorphism At run time, when it is known what type of object is
pointed to by base, then the appropriate version of the
function will be called.
The ability for objects of different classes related by inheritance to respond differently to the same message.
Polymorphism is implemented in C++ via inheritance and virtual functions.
This is also called as dynamic polymorphism. i.e. when a request is made through a base class pointer to use a virtual function, C++ chooses the correct overridden function in the appropriate derived class associated with the object.
OOP/AKN/Part_III/79
What is an Exception?Exceptions refer to unusual conditions in a
program, which may lead to errors at the time of execution.
An error generated by the program at run-time which would normally terminate the execution of the program such as
memory exhaustion,
subscript range errors,
division by zero.
Stack overflow or underflow
OOP/AKN/Part_III/80
Exception Handling?
It is a mechanism that allows a program to
detect and report an “exceptional
circumstance” during execution so that
appropriate action can be taken and possibly
recover from that condition
i.e. this mechanism provides the means to
develop a fault tolerant system
The alternative is to terminate the program.
OOP/AKN/Part_III/81
Structure of exception handlingtry {
...
throw exception
...
}
catch ( exception1){
handler1...
}
catch ( exception2){
handler2...
} ...
try block
Detects and raises an exception
catch block
Catches and handles the exception
Exception
object
OOP/AKN/Part_III/82
Example: divide by zeromain(){
int num,denom;
cout<<“Enter numrator and
denominator”; cin>>num>>denom;
try{
if (denom==0) throw denom;
cout<<num/denom;
}
catch (int i){
cout<<“divide by zero exception…”;
}
cout<<“end of program”;
}//end of main function
OOP/AKN/Part_III/83
Exampleclass DivideByZero{
char *msg;
public:
DivideByZero():msg(“Divide by zero…\n”){ }
char *what( ){return msg;}
};
double quotient(int num, int denom){
if(denom==0) throw Dividebyzero( );
return num/denom;
}
OOP/AKN/Part_III/84
Example contd.main(){
int num1, num2, res;
cout<<“Enter two numbers: ”;
while(cin>>num1>>num2){
try{
res=quotient(num1,num2);
cout<<“The quotient is: ”<<res;
}
catch(DivideByZero ex){
cout<<“Exception occurred: “<<ex.what();
}
cout<<“Enter the Integers:”
} // end of while
} // end of main
OOP/AKN/Part_III/85
Observations If the code in a try block does not throw an
exception, then all the catch handlers immediately following the try block are skipped and execution resumes with the first line of code after the catch handler
A throw normally specifies one operand of any type like Value of any expression or an object (exception object!)
A throw may also have no arguments
Exceptions should be thrown only within a try block. An exception thrown outside a try block causes a call to terminate
OOP/AKN/Part_III/86
Example: Two Handlersmain () {
try {
char * mystring;
mystring = new char [10];
if (mystring == NULL)
throw "Allocation failure";
for (int n=0; n<=100; n++) {
if (n>9) throw n;
mystring[n]='z';
}
}// end of try block
OOP/AKN/Part_III/87
Example contd.catch (int i) {
cout << "Exception: ";
cout << "index " << i << " is out of range“;
} // end of first handler
catch (const char * str) {
cout << "Exception: " << str << endl;
} // end of second handler
} // end of main
OOP/AKN/Part_III/88
Example: Re-throwing an exception #include<exception> using std::exception;
void throwExcp(){ //exception raised inside a function
try{
cout<<“Try inside function”<<endl;
throw exception(); // exception raised
}
catch(exception e){
// one part of the exception is handled here
cout<<“Handler inside function”<<endl;
throw; // exception is re-thrown
}
} // end of function
OOP/AKN/Part_III/89
Example contd.main(){
try{
throwExcp(); // function called
cout<<“No Print”;
}
catch(exception e){ // rethrowing is handled here
//i.e. remaining part of the handler
cout<<“Handler inside main”<<endl;
}
cout<<“Program control continues…”;
} // end of main function
OOP/AKN/Part_III/90
Re-throwing an ExceptionA Handler can rethrow the exception
Syntax is throw; //without argument
A rethrown exception is detected by the next
enclosing try block and is handled by an
exception handler listed after that enclosing
try block
If no exception was thrown to begin with then
the rethrow causes a call to terminate
i.e. one part of the exception is handled in one
place and remaining part is handled in
another place.
OOP/AKN/Part_III/91
Stack Unwinding The throw statement unwinds the stack, cleaning up
all objects declared within the try block by calling their destructors.
Example
class A{
int x;
public:
A(int p):x(p){cout<<'A'<<x<<endl;}
~A(){cout<<"~A"<<x<<endl;}
}; // end of class A
void abc(); // a non-member function
OOP/AKN/Part_III/92
Stack Unwinding contd.main() {
try {
A A_main(1); // an object created
abc();
} // end of try
catch(const char * s){
cout<<s<<endl;
} // end of catch
}// end of main
void abc(){
A A_abc(2); // another object created
throw "Exception thrown from abc()";
} // end of func abc
O/P: A1, A2, ~A2, ~A1,
Exception from abc()
As can be seen, throw
destroys all objects from
the point of throw till try
block
OOP/AKN/Part_III/93
Uncaught exceptions If an exception is raised in a try block but not caught
by any of the catch blocks, then C++ provides a
method to catch those uncaught exceptions.
Example
class Sugar{ }; // a class with empty body
class Testeless{ }; // another class with empty body
void abc() (int);
main(){
try{
abc(-1);
}
OOP/AKN/Part_III/94
Uncaught Exceptionscatch (Sugar){
cout<<“caught Sugar”<<endl;
} // normal handler
catch(…){
cout<<“undefined obeject caught”<<endl;
} // default handler
}// main ends here
void abc(iny p){
if(p<0) throw Tasteless();
throw Sugar();
}
O/P: undefined object caught
OOP/AKN/Part_III/95
Limitations
If a resource has been acquired and the
statements to release these resources are
after throw statement, then the acquired
resource may locked up
Example:
void abc (int p){
A *ptr=new A[2];
if (p<0) throw “Invalid args to abc()”<<endl;
}
Destructor for new objects is not called!
Stack unwinding mechanism does not work
OOP/AKN/Part_III/96
Limitations C++ exceptions cannot be used to handle
asynchronous events because the exception and its
handler are on the same call stack.
That is, exceptions rely on scoping, whereas
asynchronous events must be handled by
completely separate code that is not part of the
normal program flow (typically, interrupt service
routines or event loops).
The Standard C signal( ) system, and any similar
system, handles asynchronous events: events that
happen outside the scope of the program, and thus
events the program cannot anticipate.
OOP/AKN/Part_III/97
TemplatesTemplates provide support for generic
programming by using types as parameters
Templates give us the means of defining a family of functions or classes that share the same functionality but which may differ with respect to the data type used internally.
A class template is a framework for generating the source code for any number of related classes.
A function template is a framework for generating related functions.
OOP/AKN/Part_III/98
Function TemplatesOverloaded function are normally used to
perform similar operations on different types of data
A function can be defined in terms of an unspecified type.
If the functions are identical for each type, this may be performed more compactly and conveniently using function templates
The compiler generates separate versions of the function based on the type of the parameters passed in the function calls.
OOP/AKN/Part_III/99
Function Templatetemplate < typename T >
return-type function-name(T parm)
one parameter function.
T is called template parameter. T can be any
predefined or user defined type
Example
template< typename T >
void printArray(T *ary, int sz);
OOP/AKN/Part_III/100
Function Template
Above function template declares a single
formal type parameter „T‟ for the type array to
be printed
When the compiler detects an invocation, the
type of T is substituted throughout the template
definition and it creates a compete template
function for printing an array of specified data
type.
Then the newly created function is compiled
OOP/AKN/Part_III/101
Example Swap
Swap
Function Template
Swap
2 integers
Swap
2 floats
Swap
2 Strings ...
...
generic
OOP/AKN/Part_III/102
Example Swaptemplate < typename TParam>
void Swap( TParam &x, TParam &y){
TParam temp;
temp = x;
x = y;
y = temp;
}
OOP/AKN/Part_III/103
Function Template
We can design overloaded function templates
with additional parameters.
A function template can also be overloaded by
providing other non-template functions with
same name and different no of arguments
Compiler performs a matching process to
determine, what function to call when a function
is invoked
If no match or multiple match is found than a
compiler error will be generated.
OOP/AKN/Part_III/104
Class Templates
It is possible to design a generic class called
class template
These are also called parameterized types
because they require one or more type as
parameters to specify how to customize a
generic class (template) to form a specific
template class.
This feature is helpful in designing the
container classes.
OOP/AKN/Part_III/105
Class Template
Declare and define an object:
template < typename T>
class MyClass{
//...
}
MyClass <int> x;
MyClass <student> aStudent;
OOP/AKN/Part_III/106
Class Template
Stack
Class Template
integer
Stack
float
Stack
String
Stack
...
...
generic
OOP/AKN/Part_III/107
Example: Stack Class Templatetemplate < typename T>
class Stack{
int size;
int top;
T *stackPtr;
bool isEmpty(){return top==-1;}
bool isFull(){return top==size-1;}
public:
Stack(int=10);
~Stack(){delete [] stackPtr;}
bool push(T&);
bool pop(T&); };
OOP/AKN/Part_III/108
Stack Class Templatetemplate< typename T>
Stack<T>::Stack(int s){
size=s>0?s:10;
top=-1;
stackPtr=new T[size]; }
template< typename T>
bool Stack<T>::push(T &pushVal){
if (!isFull()){
stackPtr[++top]=pushVal;
return true; }
return false; }
OOP/AKN/Part_III/109
Stack Class Template
template < typename T>
bool Stack<T>::pop(T &popVal){
if(!isEmpty()){
popVal=stackPtr[top--];
return true;
}
return false;
}
OOP/AKN/Part_III/110
Example: Stack Class Template
main(){
Stack<double> dblStack(5);
double f=1.1;
cout<<"Pushing to Stack\n";
while(dblStack.push(f)){
cout<<f<<' ';
f+=1.1;
}
cout<<“ Double Stack full\n";
OOP/AKN/Part_III/111
Stack Class Templatewhile(dblStack.pop(f)){
cout<<f<<' ';
}
cout<<"Stack empty\n";
Stack<int> intStack(5);
int i=1;
cout<<"Pushing to Stack\n";
while(intStack.push(i)){
cout<<i<<' ';
i++;
}
cout<<"Stack full\n";
OOP/AKN/Part_III/112
Stack Class Templatewhile(intStack.pop(i)){
cout<<i<<' ';
}
cout<<"Stack empty\n";
} // End of main function
OOP/AKN/Part_III/114
Using a FileWriting to a File
I/P device Memory
Memory Disk
Reading from a File
Disk Memory
Memory O/P device
OOP/AKN/Part_III/115
Create (or write to) a File1. Declare a stream variable name
ofstream fout;
fout is the stream object (variable) name
2. Open the file
fout.open("scores.dat", ios::out);
"scores.dat" is the name of the file
ios::out is the stream operation mode (optional)
3. Write data to the file
fout<<grade<<endl;
fout<<"Mr. Spock\n";
OOP/AKN/Part_III/116
Create (or write to) a File4. Close the file
fout.close( );
Closing the file writes any data remaining in the
buffer to the file, releases the file from the
program, and updates the file directory to reflect
the file's new size.
OOP/AKN/Part_III/117
Writing to a File#include <fstream>
main(){
ofstream out;
out.open(“text”, ios::out);
int acc; char name[30], double bal;
while(cin>>acc>>name>>bal){
out<<acc<<„ „<<name<<„ „<<bal<<endl;
cout<<„:‟;
}
out.close();
} // end of main function
OOP/AKN/Part_III/118
Reading from a Filemain(){
ifstream infile(“text”, ios::in);
int acc; char name[30]; double bal;
while(infile>>acc>>name>>bal){
cout<<acc<<endl<<name<<endl<<bal
<<endl;
}
infile.close();
}//end of main function
OOP/AKN/Part_III/119
File Open Modes
ios::app //Write output to end of file
ios::ate Move to end of file. Allows
data to be written anywhere
ios::in //Open file for input
ios::out //Open file for output
ios::trunc //erase file contents
ios::nocreate //if file does not exist, the operation fails
ios::noreplace //if the file exists, the operation fails
OOP/AKN/Part_III/120
Copy content of one file into another#include<fstream>
main(){
fstream fin,fout; char c;
fin.open(“file1”, ios::in);
fout.open(“file2”, ios::out);
while(!fin.eof()){
fin.get(c);
fout.put(c);
}
fin.close(); fout.close();
}//end of main function
OOP/AKN/Part_III/121
ReadingsProgramming Bjarne Stroustrup, The C++ Programming Language, PE
Lippman, Lajoie, C++ Primer, Addison-Wesley
B. Eckel, Thinking in C++, Vol I and Vol II
Deitel & Deitel, C++ How to program
Schildt, C++ The complete reference
S. Sahay, OOP with C++
E. Balagurusami, Object oriented programming with C++
Concepts G.Booch, Object Oriented Analysis & Design
Bertand Meyer, Object Oriented Software Construction