Object Oriented Programming using C++ Part III

122
OOP/AKN/Part_III/1 Object Oriented Programming Using C++ Part III Ajit K Nayak, Ph.D. SOA University

Transcript of Object Oriented Programming using C++ Part III

OOP/AKN/Part_III/1

Object Oriented Programming

Using C++

Part III

Ajit K Nayak, Ph.D.

SOA University

OOP/AKN/Part_III/2

Contents

1. Inheritance

2. Polymorphism

3. Exception

4. Template

5. File

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/9

Person superclass

Administrator Faculty Student

subclasses

Example:

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/29

ExamplePoint

xCo: int

yCo: int

Circle

radius: double

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/60

Contents

1. Virtual functions

2. Polymorphism

3. Abstract Class

OOP/AKN/Part_III/61

Example

Base

show()

Derv1

show()

Derv2

show()

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/70

Example Shape

width:int

height:int

area()

Rectangle

area()

Triangle

area()

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/113

Stream Input/Output

ios

ostreamistream

fstream

ifstream iostream ofstream

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

OOP/AKN/Part_III/122

Thank You