5. 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.
6. 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.
7. 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.
8. 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.
16. OOP/AKN/Part_III/16
Observations
Public 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)
20. 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.
27. 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.
28. 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.
31. 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; }
33. OOP/AKN/Part_III/33
Categories of Inheritance
Single(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
34. 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
35. OOP/AKN/Part_III/35
Exp: Multi Level Inheritance
Student
Roll
getRoll()
PrintRoll()
Test
Mark1
Mark2
getMark()
PrintMark()
Result
Total
displayMark()
36. OOP/AKN/Part_III/36
Example multi level Inheritance
class Student{
protected:
int roll;
public:
void getRoll(int a){roll=a;}
void printRoll(void){
cout<<“Roll:”<<roll<<endl;
}
};
37. 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;
} };
40. 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
41. 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
42. 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).
48. OOP/AKN/Part_III/48
Example with pointers to objects
main(){
Base1 b1(10), *b1Ptr;
Base2 b2(„z‟), *b2ptr;
Derived d(7,‟A‟,3.5);
b1Ptr=&d; cout<<b1Ptr->getData();//?
b2Ptr=&d; cout<<b2Ptr->getData();//?
}
49. OOP/AKN/Part_III/49
Observations
1. 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
50. 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 dangerous
assignment!!!
8. In this case compiler does not perform an implicit
conversion.
53. 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 */
55. OOP/AKN/Part_III/55
Exp: Multi Level Inheritance
Student
Roll
getRoll()
PrintRoll()
Test
Mark1
Mark2
getMark()
PrintMark()
Result
Total
displayMark()
56. OOP/AKN/Part_III/56
Example multi level Inheritance
class Student{
protected:
int roll;
public:
void getRoll(int a){roll=a;}
void printRoll(void){
cout<<“Roll:”<<roll<<endl;
}
};
57. 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;
} };
63. 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 because
The 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
64. 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.
65. 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
67. 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.
68. 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
69. 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!!!
78. 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.
79. 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
80. 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.
81. OOP/AKN/Part_III/81
Structure of exception handling
try {
...
throw exception
...
}
catch ( exception1){
handler1...
}
catch ( exception2){
handler2...
} ...
try block
Detects and raises an
exception
catch block
Catches and handles
the exception
Exception
object
82. 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
84. 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
85. 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
86. OOP/AKN/Part_III/86
Example: Two Handlers
main () {
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
87. 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
88. 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
89. 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
90. OOP/AKN/Part_III/90
Re-throwing an Exception
A 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.
91. 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
92. 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
93. 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);
}
95. 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
96. 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.
97. OOP/AKN/Part_III/97
Templates
Templates 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.
98. OOP/AKN/Part_III/98
Function Templates
Overloaded 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.
99. OOP/AKN/Part_III/99
Function Template
template < 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);
100. 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
103. 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.
104. 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.
115. OOP/AKN/Part_III/115
Create (or write to) a File
1. 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. Spockn";
116. OOP/AKN/Part_III/116
Create (or write to) a File
4. 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.
117. 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
118. OOP/AKN/Part_III/118
Reading from a File
main(){
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
119. 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
120. 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
121. OOP/AKN/Part_III/121
Readings
Programming
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