Object Oriented Programming: - Page 1
Object Oriented Programming: - Page 1
USING
C++
•Page 1
INTRODUCTION
•Page 2
Objectives
•Page 3
The Structured Approach
•Page 4
The Structured Approach
•Page 5
The Structured Approach
•Page 6
Object-Orientation – A Paradigm Shift
•Page 7
Classification
•Page 8
Class
•Page 9
Inheritance
• The class from which other classes are derived is called the
Base class/Superclass
•Page 10
Generalization/Specialization
•Page 11
Abstract Classes
•Page 12
Overriding Behaviours
•Page 13
Overridden Behaviours
•Page 14
Polymorphism
•Page 15
Abstraction
•Page 16
Encapsulation
•Page 17
Abstraction Vs. Encapsulation
•Page 18
Abstraction Vs. Encapsulation
•Page 19
OOPL – Implementation Issues
•Page 20
User-Defined Data Types
•Page 21
Operations on User-Defined Data Types
•Page 22
Operations on User-Defined Data Types
•Page 23
Operations on User-Defined Data Types
•Page 24
Abstract Data Types (ADT)
•Page 25
Class
•Page 26
Classes and Objects
•Page 27
The Object-Message Paradigm
• Objects communicate with one another using messages.
•Page 28
The Object-Message Paradigm
•Page 29
Object-Based, Class-Based and Object-
Oriented Languages
•Page 30
Procedural vs OOP
•Page 31
Summary
•Page 32
A tour of C++
•Page 33
Objectives
•Page 34
Features of C++
•Page 35
History
•Page 36
Functions
• format
return_type function_name(argument list)
•Page 37
Preparing to Program
•Page 38
Data Types
C + + d a ta ty p e s
U s e r d e f in e d b u ilt in d e r iv e d t y p e
In te g r a l ty p e V o id F lo a t in g t y p e
in t char f lo a t d o u b le
•Page 39
User-Defined Data types
•Page 40
Data Types
• Arrays
– Array size cannot be exactly equal to length of string.
ex. char str[5]=“Hello” not allowed but char
str[6]=“Hello” is allowed
• Pointers
– Constant Pointer and pointer to a constant
– char * const constptr = “Hello”;
– int const *ptrconst=&a;
•Page 41
Variables
char cMyChar;
unsigned long nObjectID; gives type and name of variable
int nHours, nMinutes, nSeconds;
int nAnswer = 42;
float fMyTemp = 98.6;
•Page 42
Control Structures
• Control structures
– selection
• if - else (Two way branch)
• switch (Multiple branch)
– loop
• do - while (Exit control)
• while (Entry control)
• for (------do--------)
•Page 43
Default Arguments
•Page 44
Strong Typing
• Both the argument list and the return type of each function
are type checked during compilation. An implicit
conversion will be applied if possible.
•Page 45
Function Overloading
•Page 46
Ambiguity in function overloading
•Page 47
Const Qualifiers
•Page 48
Inline Functions
•Page 49
Inline Vs. Macros
•Page 50
Inline Vs. Macros
•Page 51
Inline Vs. Macros
• To compute the square of a given number, either a macro or an inline function
can be used as follows:
• #define square(x) x*x
• OR
• inline int square(int x)
• { return (x*x); }
• void main( )
• {
• cout << square( 1 + 2) << “\n”;
• }
•Page 52
The new operator
•Page 53
The delete operator
•Page 54
malloc() / free() Versus new / delete
• Easier syntax and ability to work with a variety of data types
without being required to do some clumsy typecasting.
•Page 55
Type Cast Operator
The C++ cast operator is used to explicitly request a type conversion. The
cast operation has two forms.
int intVar;
float floatVar = 104.8 ;
104.8 104
floatVar intVar
•Page 56
Function Argument Passing Mechanisms
C/C++ call convention is pass-by-value
void swap ( int x, int y )
{
int nTemp = x;
x = y;
y = nTemp;
}
•Page 57
Reference
• A reference is essentially an implicit pointer.
•Page 58
Reference Parameters
•Page 59
Reference Parameters
• int x
• x = 10;
• cout << x << “ negated is “;
• negate (&x);
• cout << x << “\n”;
• return 0;
• }
• void negate (int *i)
• {
• *i = -*i;
• }
•Page 61
Automatic Call-By-Reference
•Page 62
Summary
•Page 63
CLASSES AND OBJECTS
•Page 64
Objectives
•Page 65
Class
• General form:
class class name
{
access specifire:
data declaration
function declaration
};
•Page 66
Demonstration: difference between Class and
structure
•Page 67
Example: Structure and its objects
• define the set of functions to set and get the values of the x
and y coordinates of point.
•
•Page 68
Example: Structure and its objects
•Page 69
Example: Structure and its objects
•Page 70
Example: Structure and its objects
•Page 71
Example: Structure and its objects
•Page 72
Example: Structure and its objects
• main( )
• {
• int a, b;
• // a structure variable p1 of point type, struct keyword not required
• point p1;
• p1.setx(22); // set the value of x_coord of p1
• p1.sety(44); // set the value of y_coord of p1
• a = p1.getx( ); // return the value of the x_coord member of p1
• b = p1.gety( ); // return the value of the y_coord member of p1
• }
• Variables and methods declared within a struct are freely accessible to
functions outside the structure declaration.
•Page 73
Scope
• C++ provides for three types of scope: file, class and local
scope.
•Page 74
File Scope
•Page 75
Local Scope
•Page 76
Class Scope
•Page 77
Class Declaration
class point main( )
{ {
int x_coord; int a, b;
int y_coord; point p1;//class variable(object)
void setx( int x) p1.setx(22); // not being accessible
{ x_coord = (x > 79 ? 79 : (x < 0 ? 0 :x)); } p1.sety(44); // not being accessible
void sety (int y) a = p1.getx( ); // not being accessible
{ y_coord = (y < 24 ? 24 : (y < 0 ? 0 : y)); } b = p1.gety( ); // not being accessible
int getx( void) }
{ return x_coord; }
int gety( void)
{ return y_coord;}
}; // end of class
•Page 78
Accessibility of Struct Members
•Page 79
Accessibility of Class Members
• On the other hand, when a class declaration is used for the Point
data type as depicted earlier, the data members and the member
functions are accessible from only within the class.
•Page 80
Access Specifiers
•Page 81
Access Specifiers
•Page 82
Class Declaration for Point
• class point
• {
• private:
• int x_coord;
• int y_coord;
•
• public:
• void setx( int x)
• { x_coord = (x > 79 ? 79 : (x < 0 ? 0 :x)); }
• void sety (int y)
• { y_coord = (y < 24 ? 24 : (y < 0 ? 0 : y)); }
• int getx( void)
• { return x_coord; }
• int gety( void)
• { return y_coord;}
• }; // end of class
•Page 83
Class Declaration for Point
• main( )
• {
• int a, b;
• // an object p1 of class type point, class keyword not required
• point p1;
• p1.setx(22); // set the value of x_coord of object p1
• p1.sety(44); // set the value of y_coord of object p1
• a = p1.getx( ); // return the value of the x_coord member of object p1
• b = p1.gety( ); // return the value of the y_coord member of p1
• }
•Page 84
Initializing Member Data in an Object of a
Class
•Page 85
Constructors
•Page 86
Class With Constructors
• class point
• {
• private:
• int x_coord;
• int y_coord;
•
• public:
• point( )
• { x_coord = y_coord = 0;}
• point( int x, int y)
• {
• x_coord = (x > 79 ? 79 : (x < 0 ? 0 :x));
• y_coord = (y < 24 ? 24 : (y < 0 ? 0 : y));
• }
•
•Page 87
Class With Constructors
•Page 88
Constructors: Features
• Can be overloaded.
•Page 89
Destructors
•Page 90
The this pointer
• this ponter holds the address of the object which invokes the function
• Consider the following code:
• class point
• {
• private:
• int x_coord;
• int y_coord;
•
• public:
• void setx( int x)
• { x_coord = (x > 79 ? 79 : (x < 0 ? 0 :x)); }
• void sety (int y)
• { y_coord = (y < 24 ? 24 : (y < 0 ? 0 : y)); }
• int getx( void)
• { return x_coord; }
• int gety( void)
• { return y_coord;}
• }; // end of class
•Page 91
The this pointer
• main( )
• {
• int a, b;
• // an object p1 of class type point, class keyword not required
• point p1,p2;
• p1.setx(22); // set the value of x_coord of object p1
• p1.sety(44); // set the value of y_coord of object p1
• a = p1.getx( ); // return the value of the x_coord member of object p1
• b = p1.gety( ); // return the value of the y_coord member of p1
• p2.setx(10);
• p2.sety(20);
• }
•Page 92
The this pointer
void setx(int x) { }
void sety(int y) { }
int getx(void) { }
int gety(void) { }
int x_coord = 10
int x_coord = 22
int y_coord = 20
int y_coord = 44
p1 p2
•Page 93
The this pointer
•Page 94
Scope Resolution Operator ::
•Page 95
Scope Resolution Operator ::
Consider the following example:
class point
{
private:
int x_coord;
int y_coord;
public:
point (int x, int y);
void setx (int x);
};
point::point (int x, int y)
{
x_coord = x;
y_coord = y; }
void point::setx( int x)
{ x_coord = x; }
•Page 96
Static Class Members – Static Data Members
•Page 97
Static Data Members
• #include <iostream>
• using namespace std;
• class static_demo
• {
• private:
• static int a;
• int b;
• public:
• void set ( int i, int j)
• {a = i; b = j; }
• void show( );
• };
• int static_demo::a; // define the static variable a
• void static_demo::show( )
• {
• cout << “this is static a: “ << a;
• cout << this is non-static b: “ << b; << ‘\n’; }
•Page 98
Static Data Members
• int main( )
• {
• static_demo x, y;
• x.set(1, 1); //set a to 1
• x.show( );
• y.set(2, 2); // change a to 2
• y.show( );
• x.show( ); /* Here, a has been changed for both x and y because a is shared
• by both objects */
• return 0;
• }
•
•
•Page 99
Static Data Members – Uses
• #include <iostream.h>
• class counter_test
• {
• public:
• static int count;
• counter_test ( ) { count++; }
• ~counter_test ( ) { count--;}
• };
•Page 100
Static Data Members – Uses
• int counter_test::count;
• void f( );
• int main( )
• {
• counter_test ob1;
• cout << objects in existence: “ << counter_test::count << “\n”;
• counter_test ob2;
• cout << objects in existence: “ << counter_test::count << “\n”;
• f( );
• cout << objects in existence: “ << counter_test::count << “\n”;
• return 0; }
• void f( )
• {
• counter temp;
• cout << objects in existence: “ << counter_test::count << “\n”;
• // temp is destroyed when f( ) returns
• }
•
•
•Page 101
Static Member Functions
•Page 102
Static Member Functions
•Page 103
Static Member Functions
• #include <iostream>
• using namespace std;
• class static_type
• {
• private:
• static int i;
• public:
• static void init ( int x)
• { i = x; }
• void show ( )
• { cout << i;}
• };
• int static_type::i; // define i
•Page 104
Static Member Functions
• int main( )
• {
• // initialize static data before object creation
• static_type::init(100);
• static_type x;
• x.show( ); // displays
• return 0;
• }
•Page 105
Summary
•Page 106
Inheritance
•Page 107
Objectives
•Page 108
Inheritance
•Page 109
Code Reuse
•Page 110
Generalization/Specialization
•Page 111
Code Syntax for Inheritance
•Page 112
Access Specifier - Public
•Page 113
Access Specifier – Public (Code)
• #include<iostream>
• using namespace std;
• class base
• {
• private:
• int i, j;
• public:
• void set( int a, int b)
• { i = a;
• j = b; }
• void show( )
• {
• cout << i << “ “ << j << “\n”;
• }};
•Page 114
Access Specifier – Public (Code)
• class derived : public base
• {
• private:
• int k;
• public:
• derived (int x)
• { k = x; }
• void showk( )
• { cout << k << “\n”;} };
• int main( )
• {
• derived ob(3);
• ob.set(1,2); // access member of base from derived object
• ob.show( ); // access member of base
• ob.showk( ); // uses member of derived class
• return 0; }
•Page 115
Access Specifier - Private
• When the base class is inherited by using the private access specifier,
all public and protected members of the base class become private
members of the derived class.
• The following program will not even compile because both set( ) and
show( ) are now private members of derived:
• #include<iostream>
• using namespace std;
• class base
• {
• private:
• int i, j;
• public:
• void set( int a, int b)
• { i = a;
• j = b; }
•Page 116
Access Specifier - Private
• void show( )
• { cout << i << “ “ << j << “\n”; }
• };
• class derived : private base
• {
• private:
• int k;
• public:
• derived (int x)
• { k = x; }
• void showk( )
• { cout << k << “\n”;}
• };
•Page 117
Access Specifier - Private
• int main( )
• {
• derived ob(3);
• ob.set(1,2); //error, can’t access set( ) from outside derived
• ob.show( ); // error, can’t access show( ) from outside derived
• return 0;
• }
•Page 118
Inheritance and Protected Members
•Page 119
Inheritance and Protected Members
• #include<iostream>
• using namespace std;
• class base
• {
• protected:
• int i, j;
• public:
• void set( int a, int b)
• { i = a;
• j = b; }
• void show( )
• {
• cout << i << “ “ << j << “\n”; }
• };
•Page 120
Inheritance and Protected Members
• class derived : public base
• {
• private:
• int k;
• public:
• Void setk ( )
• { k = i * j; } // access to protected members
• void showk( )
• { cout << k << “\n”;} };
• int main( )
• {
• derived ob(3);
• ob.set(1,2); //OK, known to derived
• ob.show( ); // OK, known to derived
• ob.setk( );
• ob.showk( );
• return 0; }
•Page 121
Inheritance and Protected Members
• When a derived class is used as a base class for another derived class,
any protected member of the initial base class that is inherited by the
first derived class may also be inherited as protected again by a second
derived class.
•Page 122
Inheritance and Protected Members
• public:
• void set( int a, int b)
• { i = a;
• j = b; }
• void show( )
• {
• cout << i << “ “ << j << “\n”; } };
• class derived1 : public base
• {
• private:
• int k;
• public:
• Void setk ( )
• { k = i * j; }
• void showk( )
• { cout << k << “\n”;} };
•Page 123
Inheritance and Protected Members
• class derived2 : public derived1
• {
• private:
• int m;
• public:
• void setm ( )
• { m = i – j; }
• void showm( )
• {cout << m << “\n”;} };
• int main( )
• {
• derived1 ob1;
• derived2 ob2;
• ob1.set(2, 3);
• ob1.show( );
•Page 124
Inheritance and Protected Members
• ob1.setk( );
• ob1.showk( );
• ob2.set(3,4)
• ob2.show ( );
• ob2.setk( );
• ob2.setm( );
• ob2.showk( );
• ob2.showm( );
• return 0;
• }
•Page 125
Inheritance and Protected Members
• If however, base were inherited as private, then all members of base would become private
members of derived1, which means they would not be accessible by derived2
#include<iostream>
using namespace std;
class base
{
protected:
int i, j;
public:
void set( int a, int b)
{ i = a;
j = b; }
void show( )
{cout << i << “ “ << j << “\n”; }
};
•Page 126
Inheritance and Protected Members
• class derived1 : private base
• {
• private:
• int k;
• public:
• void setk ( )
• { k = i * j; }
• void showk( )
• { cout << k << “\n”;} };
•Page 127
Inheritance and Protected Members
• void showm( )
• {cout << m << “\n”;}
• };
• int main( )
• {
• derived ob1;
• derived ob2;
• ob1.set (1, 2); // error, can’t use set( )
• ob1.show( ); //error, can’t use show( )
• ob2.set(3, 4); // error, can’t use set( )
• ob2.show( ); // error, can’t use show( )
• return 0;
• }
•Page 128
Protected Base Class Inheritance
•Page 129
Protected Base-Class Inheritance
• void showij( )
• {
• cout << i << “ “ << j << “\n”; } };
• class derived : protected base
• {
• private:
• int k;
• public:
• void setk( )
• {
• setij(10,12);
• k = i * j; }
• void showall( )
• { cout << k << “\n”;
• showij( ); }
• };
•Page 130
Protected Base-Class Inheritance
• int main( )
• {
• derived ob;
• ob.setij( ); // illegal, setij( ) is protected member of derived
• ob.setk( ); // OK, public member of derived
• ob.showall( ); // ok, public member of derived
• ob.showij( ); illegal, showij( ) is protected member of derived
• return 0;
• }
•Page 131
Constructors, Destructors & Inheritance
•Page 132
Constructors, Destructors & Inheritance
•Page 133
Constructors, Destructors & Inheritance
• ~base ( )
• { cout << “Destructing base\n”; } };
• int main( )
• {
• derived ob; // do nothing but construct and destruct ob
• return 0; }
•Page 134
Constructors, Destructors & Inheritance
•Page 135
Passing Parameters to Base Class Ctors
•Page 136
Passing Parameters to Base Class Ctors
•Page 137
Passing Parameters to Base Class Ctors
• ~base( )
• { cout << “destructing base\n”; } };
•Page 138
Passing Parameters to Base Class Ctors
• ~derived( )
• { cout << “destructing derived\n”; }
• void show( )
• { cout << i << “ “ << j << “\n”; } };
• int main( )
• {
• derived ob(3,4)
• ob.show( ); // displays 4,3
• return 0; }
•Page 139
Types of inheritance
Multilevel Inheritance
• Single Inheritance A
A
C
Multiple Inheritance
Hybrid Inheritance
A B A
B C
C
•Page 140
Hybrid inheritance
A
Indirect Base class
Derived Class
C
•Page 141
Virtual Base Class
•Page 142
Inheritance Vs. Composition
• Mechanism to make use of existing classes to
define new and more complex classes.
•Page 144
Arrays, Pointers, References, and
Special Constructors
•Page 145
Objectives
•Page 146
Constructor With One Parameter
•Page 147
Constructor With One Parameter
• int geta ( )
• { return a; } };
• int main( )
• { x ob = 99; // passes 99 to j;
• cout << ob.geta( ); // outputs 99
• return 0; }
• The reason for this is that whenever you create a constructor that
takes one argument, you are implicitly creating a conversion from
the type of that argument to the type of the class.
•Page 148
Copy Constructor
•Page 149
Copy Constructor
• The same type of problem can occur in two additional ways:
- when a copy of an object is made when it is passed as an argument to a
function
- when a temporary object is created as a return value from a function.
•Page 150
Copy Constructor
•Page 151
Copy Constructor
•Page 152
Copy Constructor
• #include<iostream>
• #include<stdlib>
• Using namespace std;
• Class array
• {
• int *p;
• int size;
• public:
• array (int sz)
• { try {
• p = new int [sz];
• }
• catch (bad_alloc xa)
• { cout << “allocation failure\n”;
• exit(EXIT_FAILURE); }
• size = sz; }
•Page 153
Copy Constructor
• ~array ( )
• { delete [ ] p; }
• array (const array &a); // copy constructor
• void put (int i, int j)
• { if (i >= 0 && i < size)
• p[i] = j; }
• int get (int i)
• { return p[i]; } };
• array:: array (const array &a) //Copy constructor
• { int i;
• try {
• p = new int[ a.size];
• }catch (bad_alloc xa)
• {cout << “Allocation Failure\n”;
• exit (EXIT_FAILURE); }
• for (i=0; i < a.size; i++)
• p[i] = a.p[i]; }
•Page 154
Copy Constructor
• int main( )
• {
• array num(10);
• int i;
• for (i = 0; i < 10; i++)
• num.put (i ,i);
• for (i = 9; i >= 0; i--)
• cout << num.get(i);
• //create another array and initialize with num
• array x(num); // invoke copy constructor
• for (i = 0, i < 10; i++)
• cout << x.get( i);
• return 0;
• }
•Page 155
Arrays of Objects
•Page 156
Arrays of Objects
• int get_i( )
• { return i; } };
• int main( )
• {
• c1 ob[3];
• int i;
• for (int i = 0; i < 3; i++)
• ob[i].set_i(i+1);
• for ( i = 0; i < 3; i++)
• cout << ob[i].get_i( ) << “\n”;
• return 0;
• }
•Page 157
Arrays of Objects
• If a class defines a parameterized constructor, you may
initialize each object in an array by specifying an
initialization list, just like you do for arrays of primitive
data types.
•Page 158
Arrays of Objects
•Page 159
Arrays of Objects
• int get_i( )
• { return i; } };
• int main( )
• {
• c1 ob[3] = {1, 2, 3};
• int i;
• for ( i = 0, i < 2, i++)
• cout << ob[i].get_i( ) << “\n”;
• return 0; }
•Page 160
Arrays of Objects
• The following example illustrates passing list to a two parameter
constructor
#include<iostream>
• using namespace std;
• class c1
• {
• private:
• int h, i;
• public:
• c1( int j, int k)
• { h = j;
• i = k; }
• int get_i( )
• { return i; }
•Page 161
Arrays of Objects
• int get_h( )
• { return h; }
• int main ( )
• {
• c1 ob[3] = {c1(1, 2), c1(3, 4), c1(5, 6)} // initialize
• int i;
• for ( i = 0; i < 3; i ++)
• {
• cout << ob[i].get_h( ) << “, “<< ob[i].get_i( ) << “\n”;
• }
• return 0
• }
•Page 162
Creating Initialized & Non-Initialized Arrays
•Page 163
Creating Initialized & Non-Initialized Arrays
• class c1
• {
• private:
• int i;
• public:
• c1( )
• { i = 0; } //called for non-initialized arrays
• c1( int j)
• { i = j; }// called for initialized arrays
• int get_i( )
{ return i; } };
• Given the preceding class declaration, both of the following statements are
permissible:
• c1 a1[3] = {3, 5, 6}; //initialized
• c1 a2[34]; //un-initialized
•Page 164
Pointers to Objects
•Page 165
Pointers to Objects
• #include<iostream>
• using namespace std;
• class c1
• {
• private:
• int i;
• public:
• c1 ( )
• { i = 0; }
• c1 (int j)
• { i = j; }
• int get_i( )
• { return i; }
• };
•
•
•Page 166
Pointers to Objects
• int main( )
• {
• c1 ob[3] = {1, 2, 3 };
• c1 *p; // pointer p of class type c1
• int i;
• p = ob; // get starting offset of array
• for ( i = 0; i < 3; i++)
• {
• cout << p->get_i( ) << “\n”;
• p++; // point to the next object in the array
• }
• return 0;
• }
•Page 167
Pointers to Derived Types
• Assume two classes B and D. Further, assume that D is
derived from the base class B. In this situation, a pointer of
type B may also point to an object of type D.
• Using a base class pointer, you can access only the members
of the derived type that were inherited from the base. But,
using a base class pointer, you cannot access members added
by the derived class.
•Page 168
Pointers to Derived Types
•Page 169
Pointers to Derived Types
• class derived : public base
• {private:
• int j;
• public:
• void set_j( int num)
• { j = num; }
• int get_j( )
• { return j; } };
• int main( )
• { base *bp;
• derived d;
• bp = &d; // base pointer points to derived object
• bp->set_i( 10); //access inherited members from derived object
• cout << bp->get_i( ) << “ “;
• bp->set_j(22); //ERROR
• cout << bp->get_j( ); // ERROR
• return 0; }
•Page 170
Passing Object References
•Page 171
Passing Object References
• #include<iostream>
• using namespace std;
• class c1
• {
• int id;
• public:
• int i;
• c1( int num)
• ~c1( );
• void negate(c1 &ob)
• {ob.i = -ob.i; } };
• c1::c1(int num)
• {
• cout << “constructing “ << num << “\n”;
• id = num;
• }
•Page 172
Passing Object References
• c1::~c1( )
• { cout << “destructing “ << id << “\n”; }
• int main( )
• {c1 o(1);
• o.i = 10;
• o.negate(o);
• cout << o.i << “\n”;
• return 0; };
•Page 173
The Dot . Operator
•Page 174
Returning References
• A function may return a reference. This has the startling effect
of allowing a function to be used on the left hand side of an
assignment statement. Consider the following program:
• #include<iostream>
• using namespace std;
• char& replace (int i); //returns a reference to a character
• char s[80] = “hello there”;
• int main( )
• {replace(5) = ‘x’ //assign x to space after hello
• cout << s;
• return 0; }
• char& replace( int i)
• { return s[i]; }
•Page 176
Independent References
• #include<iostream>
• using namespace std;
• int main( )
• { int a;
• int &ref = a; // independent reference
• a = 10;
• cout << a << “ “ << ref << “\n”;
• ref = 100
• cout << a << “ “ << ref << “\n”;
• int b = 19;
• ref = b; // this puts b’s value into a
• cout << a << “ “ << ref << “\n”;
• ref - -
• cout << a << “ “ << ref << “\n”;
• return 0;
• }
•Page 177
References to Derived Types
•Page 178
Restrictions on References
•Page 179
Summary
•Page 180
Virtual Functions and
Polymorphism
•Page 181
Objectives
•Page 182
Virtual Functions
•Page 183
Virtual Functions
• The virtual function within the base class defines the form
of the interface to the function.
•Page 184
Virtual Functions
•Page 185
Virtual Functions
• #include<iostream>
• using namespace std;
• class base
• {
• public:
• virtual void vfunc( )
• { cout << “this is base’s vfunc( )\n”; } };
•Page 186
Virtual Functions
• class derived2 : public base
• {
• public:
• void vfunc( )
• { cout << “this is derived2’s vfunc( )\n”; } };
• int main( )
• { base *p, b;
• derived1 d1;
• derived2 d2;
• p = &b;
• p->vfunc( ); //access to base’s vfunc( )
• p = &d1;
• p->vfunc( ); // access derived1’s vfunc( )
• p = &d2;
• p->vfunc( ); // access derived2’s vfunc( )
• return 0; }
•Page 187
Virtual Functions
•Page 188
Virtual Functions
•Page 189
Calling a Virtual Function Through
a Base Class Reference
• The polymorphic nature of a virtual function is also
available when called through a base class reference.
•Page 190
Calling a Virtual Function Through
a Base Class Reference
• The most common situation in which a virtual function is invoked through a
base class reference is when the reference is defined as a function parameter.
Consider the following program:
• #include<iostream>
• using namespace std;
• class base
• {
• public:
• virtual void vfunc( )
• { cout << “this is base’s vfunc( )\n”; } };
•Page 191
Calling a Virtual Function Through
a Base Class Reference
• class derived2 : public base
• {
• public:
• void vfunc( )
• { cout << “this is derived2’s vfunc( )\n”; } };
• void f(base &r)
• { r.vfunc( ); }
• int main( )
• { base b;
• derived d1;
• derived d2;
• f(b); // pass a base object to f( )
• f(d1); // pass a derived object to f( )
• f(d2); // pass a derived object to f( )
• return 0; }
•Page 192
The Virtual Attribute is Inherited
•Page 193
The Virtual Attribute is Inherited
• #include<iostream>
• using namespace std;
• class base
• {
• public:
• virtual void vfunc( )
• { cout << “this is base’s vfunc( )\n”; } };
•Page 194
The Virtual Attribute is Inherited
•Page 195
Virtual Functions are Hierarchical
• When a function is declared as virtual by a base class, it
may be overridden by a derived class. However, the
function does not have to be overridden.
•Page 196
Virtual Functions are Hierarchical
• #include<iostream>
• using namespace std;
• class base
• {
• public:
• virtual void vfunc( )
• { cout << “this is base’s vfunc( )\n”; } };
•Page 197
Virtual Functions are Hierarchical
• //derived2 inherits virtual function from derived1
• class derived2 : public derived1
• { // vfunc( ) not overridden by derived2; base’s is used };
• int main( )
• { base *p, b;
• derived1 d1;
• derived2 d2;
• p = &b;
• p->vfunc( ); //access to base’s vfunc( )
• p = &d1;
• p->vfunc( ); // access derived1’s vfunc( )
• p = &d2;
• p->vfunc( ); // access base’s vfunc( ) since derived2 does not override vfunc( )
• return 0; }
•Page 198
Pure Virtual Functions
•Page 199
Pure Virtual Functions
•Page 200
Pure Virtual Functions
• The base class number contains an integer called val, the function setval( ) and
the pure virtual function show( )
• The derived class hextype, dectype, and octtype inherit number, and redefine
show( ) so that it outputs the value of val in each number base (i.e., hexadecimal,
decimal or octal).
• #include<iostream>
• using namespace std;
• class number
• {
• protected:
• int val;
• public:
• void setval( int i)
• { val = i;}
• virtual void show( ) = 0; };
•Page 201
Pure Virtual Functions
• class hextype : number
• {
• public:
• void show( )
• { cout << hex << val << “\n”; } };
•Page 202
Pure Virtual Functions
• int main( )
• {
• number *p;
• dectype d;
• hextype h;
• octtype o;
• p = &d;
• d.setval(20);
• p->show( ); // displays 20 – decimal
• p = &h;
• h.setval(20);
• p->show( ); // displays 14 – hexadecimal
• p = &o;
• o.setval(20);
• p->show( ); // displays 24 –octal
• return 0; }
•Page 203
Virtual Function Mechanics – The Virtual
Table
• C++ implements late binding by setting up a vtable. The
keyword virtual tells the compiler it should not perform early
binding.
•Page 204
Virtual Function Mechanics – The Virtual
Table
• Each instance of the class has a pointer to its class wide VTABLE.
Using this, the compiler can achieve dynamic binding.
• When you make a virtual function call through a base-class pointer, the
compiler quietly inserts code to fetch the VPTR and look up the
function address in the VTABLE, thus calling the right function and
causing late binding to take place.
• With virtual functions, the proper function gets called for an object,
even if the compiler cannot know the specific type of the object.
•Page 205
Abstract Classes
•Page 206
Using Virtual Functions
•Page 207
Using Virtual Functions
•Page 208
Using Virtual Functions
• define all common features and interfaces in a base class. In
cases where certain actions can be implemented only by the
derived class, use a virtual function.
•Page 209
Using Virtual Functions
• Consider the following example. A class hierarchy is created that performs conversions
from one system of units to another (for example, litres to gallons).
• #include<iostream>
• using namespace std;
• class convert
• {
• protected:
• double val1;
• double val2;
• public:
• convert (double i)
• { val1 = i; }
• double getconv( )
• { return val2; }
• double getinit( )
• { return val1; }
• virtual void compute( ) = 0;};
•
•Page 210
Using Virtual Functions
• //litres to gallons
• class l_to_g : public convert
• { l_to_g( double i) : convert( i ) { }
• void compute( )
• { val2 = val1 / 3.7854; } };
• // fahrenheit to celsius
• class f_to_c : public convert
• {
• public:
• f_to_c( double i) : convert( i) { }
• void compute
• { val2 = (val1 -32) / 1.8; } };
•Page 211
Using Virtual Functions
• int main( )
• {
• convert *p // pointer to abstract base class
• l_to_g lgob(4);
• f_to_c fcob(70);
• // use virtual function mechanism to convert
• p = &lgob;
• cout << p->getinit( ) << litres is “;
• p->convert( );
• cout << p->getconv( ) << “gallons\n”;
p = &fcob;
• cout << p->getinit( ) << in fahrenheit is “;
• p->compute( );
• cout << p->getconv( ) << “celsius\n”;
• return 0;
• }
•
•Page 212
Early Vs. Late Binding
•Page 213
Early Vs. Late Binding
•Page 214
Early Vs. Late Binding
•Page 215
Early Vs. Late Binding
•Page 216
Virtual Destructor
•Page 217
Summary
•Page 218
Friend Functions
•Page 219
Objectives
•Page 220
Friend Functions
•Page 221
Friend Functions
• Syntax:
friend return type Function Name()
{ statements}
• Using friend function we can access all the members of a
class from outside the class
•Page 222
Friend Functions
• Example:
• class mks_distance
• {private:
• int meter;
• int cm;
• public:
• mks_distance( int, int);
• void disp_distance( void);
• friend int compare( mks_distance &, mks_distance &); };
• mks_distance:: mks_distance( const int mt = 0, const int cmt = 0)
• {meter = mt;
• cm = cmt; }
•Page 223
Friend Functions
• void mks_distance::disp_distance( void)
• { cout << “the distance = “ << meter << ‘.’ << cm << “metres\n”; }
•Page 224
Friend Functions
•Page 225
Building Bridges of Friendship
•Page 226
Example:
• class mks_distance; // forward declaration
class fps_distance
{private:
unsigned int feet;
float inch;
public:
fps_distance(unsigned int, float); // constructor
void disp_distance (void);
/* the friend function feet_to_meter( ) can access the private members of
this class */
friend void feet_to_meter( fps_distance &, mks_distance & ); };
fps_distance :: fps_distance( unsigned int ft = 0, float in = 0)
{feet = ft;
inch = in;}=
Building Bridges of Friendship
• void fps :: disp_distance( void)
• {cout << “The distance = “ << feet << “”” << inch << “,” << ‘\n’; }
• class mks_distance
• {private:
• int meter;
• int cm;
• public:
• mks_distance( int, int);
• void disp_distance( void);
• };
• mks_distance:: mks_distance( const int mt = 0, const int cmt = 0)
• {meter = mt;
• cm = cmt; }
•Page 228
Building Bridges of Friendship
• void mks_distance::disp_distance( void)
• {cout << “the distance = “ << meter << ‘.’ << cm << “metres\n”;}
• friend void feet_to_meter(fps_distance &, mks_distance &);
• };
• /*Function to convert feet and inches to meter and centimeters. The function
receives an object of the fps_distance and the mks_distance class as
parameters. */
• void feet_to_meter( fps_distance &fps, mks_distance &mks)
• {
• int temp = ((( fps.feet 12 + fps.inch ) / 39 * 100);
• mks meter = temp / 100;
• mks.meter = temp % 100;
• }
•Page 229
Forward Declaration
•Page 230
Friend class
•Page 231
Example:Friend class
Example:
class A
{
private:
int X;
void setx(int p)
{
X=p;
}
void disx()
{
cout<<X;
}
friend class B;
};
•Page 232
Example: Friend class
class B
{ main()
private: {
int Y; B Obj;
public: Obj.setxy();
void setxy()
{ }
A obj;
Obj.setx(10);//accessing private data of class A
Obj.disx();
}
};
•Page 233
Summary
•Page 234
Operator Overloading
•Page 235
Objectives
•Page 236
Operator Overloading
•Page 237
Operator Overloading
•Page 238
Operator Overloading
• adding the two objects and storing the result in a third
object could be carried out as follows:
– object3 = object1 + object2;
•Page 239
Operator Overloading
•Page 240
Operator Overloading
• int fps_distance :: operator = =(fps_distance);
•Page 241
Precautions When Overloading Operators
•Page 242
Overloading Unary Operators
• Unary operators act on one operand. As an example, you will now overload
the + + operator for the fps_distance to increment the data member feet by 1.
• #include(iostream>
• class fps_distance
• { private:
• int feet;
• float inch;
• public:
• fps_distance (int f, float i)
• {feet = f;
• inch = i; }
• operator ++( )
• { feet++; }
• void disp_distance( )
• { cout << “distance = “ << feet << “ ‘” << inch << “ “ “; } };
•Page 243
Overloading Unary Operators
• void main ( )
• {
• fps_distance fps(10,10)
• ++fps;
• fps.disp_distance( );
• }
•Page 244
Overloading Prefix & Postfix Unary
Operators
•Page 245
Distinguishing Between Postfix & Prefix
Unary Operators
•Page 246
Distinguishing Between Postfix & Prefix
Unary Operators
• Overloading the - - operator for the fps_distance class:
• Prefix Implementation:
• fps_distance operator - - ( )
• {feet --;
• fps_distance temp(feet, inch);
• return temp; }
• Postfix Implementation:
• fps_distance operator - - (int )
• { //create a temporary object with the original value of feet
• fps_distance temp (feet, inch);
• feet- -;
• // return temp; }
•Page 247
Nameless Objects
•Page 248
Overloading Binary Operators
• You will now overload the binary “+” operator for adding
two objects of the fps_distance class.
•Page 249
Overloading Binary Operators
• #include<iostream>
• class fps_distance
• {private:
• int feet;
• float inch;
• public:
• fps_distance( int, float);
• fps_distance operator +( fps_distance&);
• void disp_distance( ); };
• fps_distance :: fps_distance( int f = 0; i = 0.0)
• { feet = f;
• inch = i; }
•Page 250
Overloading Binary Operators
• fps_distance fps_distance :: operator + (fps_distance &fps2)
• {int f = feet + fps2.feet;
• float i = inch + fps2.inch;
• if ( i >= 12)
• { i - = 12;
• f++; }
• return fps_distance( f, i); //creating an unnamed object and returning it }
•Page 251
Overloading Binary Operators
•Page 252
Overloading Overloaded Operators
• A class can have more than one function for the same
operator, i.e., the same operator can be overloaded.
•Page 253
Overloading Overloaded Operators
• The following are the two operator functions:
•Page 254
Data Conversion
• The assignment operator ( = ) can be used to assign a value
from one variable to another, or assign a constant value to
a variable.
•Page 255
Fundamental to User-Defined Conversion
•Page 256
Fundamental to User-Defined Conversion
• #include<iostream>
• class fps_distance
• {private:
• int feet;
• float inch;
• public:
• fps_distance( int inches)
• {feet = inches /12;
• inch = inches % 12; }
•Page 257
Fundamental to User-Defined Conversion
• void disp_distance( )
• {cout << feet << inch << “\n”; } };
• void main( )
• {
• fps_distance dist1 = 39;
• dist1.disp_distance( );
• dist1 = 78;
• dist1.disp_distance( );
• }
•Page 258
User-Defined to Fundamental Conversion
• The following program converts a user-defined data type to a
fundamental data type.
• #include<iostream>
• class fps_distance
• {private:
• int feet;
• float inch;
• public:
• fps_distance( int f, float i);
• {feet = f;
• inch = i; }
• void disp_distance( )
• {cout << feet << “-” << inch << “\n”; }
•
•Page 259
User-Defined to Fundamental Conversion
operator int( )
• {
• return (feet * 12 + inch);
• }
• };
• void main( )
• {
• fps_distance height( 6,3);
• height.disp_distance( );
• int inches = int( height);
• cout << inches << “\n”;
• }
•Page 260
User-Defined to Fundamental Conversion
•Page 261
Overloading the Assignment Operator
• Consider the following RationalNum class:
• class RationalNum
• {private:
• int numerator;
• int denominator;
• public:
• void display( )
• { cout << numerator << “/” << denominator; }
• RationalNum( int x, int y)
• { numerator = x;
• denominator = y; } };
• Consider the following code segment:
• RationalNum a(5,9), b;
• b = a; // assignment
• b.display( ); // outputs 5/9
•Page 262
Overloading the Assignment Operator
•Page 263
Overloading the Assignment Operator
• If the class does not contain any pointer data members, this
default assignment operator is adequate, and it causes no
problems.
•Page 264
Overloading the Assignment Operator
• illustrate it with a class that contains a pointer data member:
• class MyString
• {private:
• char* rep;
• public:
• MyString( char* str)
• {rep = new char[ strlen(str) + 1];
• strcpy( rep, str); } };
• The two calls, one for object a, and the other for object b, build two
MyString objects as follows:
•Page 265
Overloading the Assignment Operator
•Page 266
Overloading the Assignment Operator
•Page 267
Overloading the Assignment Operator
•Page 268
Overloading the Assignment Operator
• First, rhs (short for right hand side) is simply the identifier
for the parameter which will appear to the right of the
assignment operator.
•Page 269
Overloading the Assignment Operator
• It is standard to pass the parameter as a constant reference
parameter which is indicated by the const and & in the
parentheses.
•Page 270
Overloading the Assignment Operator
•Page 271
Overloading the Assignment Operator
•Page 272
Overloading the Assignment Operator
•Page 273
Overloaded Assignment Operator
and the Copy Constructor
• On the face of it, the overloaded assignment operator looks
functionally similar to a copy constructor but with two
significant differences:
it returns something: a reference
it must cleanup on the this object before assigning
•Page 274
Friendly Operator
•Page 275
Friendly Operator
•Page 276
Friendly Operator
• If the operator is defined globally, then the operands on either side
of the operator are sent down as parameters to to the operator
function.
• Thus, the global operator can have any operand of any data type
on the left hand side of an operation.
•Page 277
Friendly Operator
• class fps_distance
• {private:
• int feet;
• int inch;
• public:
• fps_distance (const int);
• fps_distance(int float);
• friend fps_distance operator + (fps_distance &, fps_distance &);
• void disp_distance( ); };
• fps_distance :: fps_distance (const int i)
• { feet = i /12;
• inch = i % 12; }
• fps_distance::fps_distance (int f = 0, float i = 0.0)
• {feet = f;
• inch = i; }
•Page 278
Friendly Operator
• fps_distance operator + ( fps_distance &fps1, fps_distance fps2)
• {int f = fps1.feet +fps2.feet;
• float i = fps1.inch + fps2.inch;
• if (i >= 12.0)
• {i-= 12;
• f++;
• return fps_distance(f,i); }
•Page 279
Summary
•Page 280
C++ Streams
•Page 281
Objectives
•Page 282
Streams
•Page 283
Advantages of the Stream Classes
•Page 284
The Stream Class Hierarchy
ios
istream ostream
iostream
•Page 285
Standard Output
•Page 286
Stream Extraction & Standard Input
•Page 287
Integer Extraction
• cin is an object of type istream defined in the header file iostream, and
associated with the standard input device, i.e., the keyboard.
• int i;
• cin >> i;
• If the input from the user through the keyboard is <space> <space>
787w33, then i will contain 787.
• The input buffer will now contain w33, and the pointer will be
positioned at w. this is because integer extraction bypasses white
spaces, and reads input characters until it encounters a character that
cannot be part of that type.
•Page 288
Character Extraction
• The character extractor might not work the way one might
expect it to. It reads the next character in the stream after
skipping white spaces.
•Page 289
Character Extraction
•Page 290
Implicit File Opening and Closing
•Page 291
Extraction & Insertion of Fundamental
Data Types
• #include<iostream>
• using namespace std;
• void main( )
• {
• ofstream out(“int.tst”);
• out << 25 << ‘ ‘ << 4567 << ‘ ‘ << 8910
• }
•Page 292
Extraction & Insertion of Fundamental
Data Types
• #include<iostream>
• using namespace std;
• void main( )
• {
• ifstream in(“int.tst”);
• int i, j, k;
• in >> i >> j >> k;
• cout << i << ‘ ‘ << j << ‘ ‘ << k;
• }
•Page 293
Extraction & Insertion of Fundamental
Data Types
• Strings in File I/O
• #include <fstream.h>
• void main( )
• { ofstream out(“STR.TST”);
• out < “This is a test string”; }
• #include <fstream.h>
• void main( )
• {
• ifstream in(“STR.TST”);
• char str[30];
• in >> str;
• cout << str;
• }
•Page 294
File I/O Using Objects
• Consider the following code:
• #include<fstream>
• #include<string.h>
• class vehicle
• {
• public:
• int serialno;
• char model[8];
• double price; };
• void main( )
• { ofstream out(“obj.tst”);
• vehicle car;
• car.serialno = 22;
• strcpy(car.model, “astra”);
• car.price = 600000.00;
• out << car.serialno << car.model << car.price; }
•Page 295
File I/O Using Objects
• The following program shows the input of objects from a file:
• #include<fstream>
• class vehicle
• {
• public:
• int serialno;
• char model[8];
• double price; };
• void main( )
• { ifstream in(“obj.tst”);
• vehicle car;
• in >> car.serialno;
• in >> car.model;
• in >> car.price;
• cout << ‘\n’ << car.serialno << ‘\n’ << car.model << ‘\n’ << car.price; }
•Page 296
Binary I/O
• So, ‘A’ would be written as ‘A’ on to the file. And the number
-12345.678 will be written as -12345.678. This means that you
can type the file and see the contents.
•Page 297
Binary I/O
•Page 298
Binary I/O – Character I/O
• The stream classes have many member functions for file I/O. Two of
these are get( ) and put( ).
• The get( ) function reads a character from a file, while the put( )
function writes a character on to a file.
• #include<fstream>
• #include<string.h>
• void main( )
• {
• ofstream outfile(“chrfile.tst”);
• char str[ ] = “this is a test”;
• for (int i = 0; i < strlen(str); i++)
• outfile.put(str[i];
• outfile.put(‘\0’);
• }
•Page 299
Binary I/O – Character I/O
•Page 300
Binary I/O – String I/O
•Page 301
Binary I/O – String I/O
• #include<iostream>
• void main( )
• {
• char str[20];
• cin.get (str, 20);
• cout << str;
• }
• This program gets a string (along with white spaces) from the standard
input, and displays the string on standard output.
•Page 302
Binary I/O – String I/O
•Page 303
Binary I/O – Integer I/O
• Methods:
• read( ) called with two arguments
– The address of the buffer into which the file is to be read
– The size of the buffer
•Page 304
Binary I/O – Integer I/O
• #include<fstream>
• void main( )
• {
• ofstream outfile(“intfile.tst”);
• int number = 0;
• while ( number != 999)
• {
• cout << “please input an integer”;
• cin >> number;
• outfile.write((char *) &number, sizeof(number));
• }
•Page 305
Binary I/O – Integer I/O
• #include<fstream>
• void main( )
• {
• ifstream intfile(“INTFILE.TST”);
• int number = 0;
• intfile.read((char *)&number, sizeof(number));
• while(intfile) // EOF check
• {
• cout << number;
• intfile.read((char *)&number, sizeof(number));
• }
• }
•Page 306
Explicit File Opening and Closing
•Page 307
Opening a File for Input and Output
•Page 308
The Open Mode Bits
• Some of these bits are used for formatting input and output.
Some others are used for error handling. By inheritance,
these are available for the fstream classes.
•Page 309
The Open Mode Bits
• These open mode bits represent the mode in which the file
is opened. Collectively, these bits state the mode in which
the file is to be opened.
•Page 310
The Open Mode Bits
Mode Explanation
app All data written out is appended to the stream
ate The file pointer starts at the end of the stream, i.e.,
causes a seek to the end of the file. I/O operations can
still occur anywhere within the file
in The stream is opened for input.
•Page 311
The Open Mode Bits
Mode Explanation
•Page 312
Disk I/O Using Member Functions
• class Drug
• {
• private:
• unsigned int batchno;
• char drugCode[5];
• char category;
• char units[4];
• float qtyProduced;
• public:
• void getdata( )
• { cout << “\nEnter Batch Number:”;
• cin >> batchno;
• cout << “\nEnter Drug Code :”
• cin >> drugCode;
• cout << “\nEnter Category :”;
• cin >> category;
• cout << “\nEnter Unit of Measurement :”;
•Page 313
Disk I/O Using Member Functions
• cin >> units;
• cout << “\nEnter Quantity Produced :”;
• cin >> qtyProduced; }
•Page 314
Disk I/O Using Member Functions
• Class Drug_file
• {
• private:
• drug buffer;
• public:
• void diskout( void)
• void diskin( void) };
•Page 315
Disk I/O Using Member Functions
• void drug_file :: diskout (void)
• {ofstream ofile(“drugs.dat”, ios::app);
• char loop;
• do {
• buffer.getdata( );
• ofile.write((char *)&buffer, sizeof(buffer);
• cout << “\n any more records (y/n) ?”;
• cin >> loop;
• } while (loop = = ‘y’); }
•Page 316
Disk I/O Using Member Functions
• void main( )
• {
• drug_file fileobj;
• //get data and write to the file
• fileobj.diskout( );
• //read file and display records
• fileobj.diskin( );
• }
•Page 317
Disk I/O Using Member Functions
• Here, infile becomes zero when EOF is reached. The ios::nocreate flag reports
an error when opening, if the file does not already exist. The modified
diskin( ) funciton is shown below:
• void drug_file :: diskin(void)
• {
• ifstream ifile(“DRUGS.DAT”, ios::nocreate);
• if (ifile)
• {
• ifile.read((char *)&buffer, sizeof(buffer);
• while(ifile)
• { buffer.showdata( );
• ifile.read((char *)&buffer, sizeof(buffer)) }
• }
• else
• { cout << “\n file does not exist”; } }
•
•Page 318
The Stream Status Bits
•Page 319
The Stream Status Bits
Name Description
•Page 320
Member Functions for Accessing Stream
Status Bits
Name Description
int good( ) returns a non-zero value if the stream is ok, zero otherwise.
int bad( ) returns a non-zero value if the badbit or hardfail bits are set,
else returns 0.
int eof( ) returns a on-zero value if the eofbit is set, else returns 0.
int fail( ) returns a non-zero value if the failbit, badbit, or hardfail bit
void set the error flags equal to ef. by default, ef equals 0, which
clear( int resets all the error bits
ef=0)
•Page 321
Random Access
•Page 322
Random Access
• The seekg( ) and the tellg( ) functions allow you to set and
examine the get pointer.
• The seekp( ) and the tellp( ) functions allow you to set and
examine the put pointer.
•Page 323
Random Access
•Page 324
Random Access
Name Description
ios::beg The beginning of the file
•Page 325
Random Access
• If supplied with only one argument, ios::beg is assumed by
default. For example, in the statement: file.seekg(16),
ios::beg will be the reference point by default.
•Page 326
Random Access Scenario
Example : to find out the how many Drug records are there in the file.
• void main( )
• {
• drug drugobj;
• fstream ifile(“drugs.dat”, ios::in);
• ifile.seekg(0, ios::end);
• long endpos = ifile.tellg( );
• cout << “\n the size of the file is “ << endpos;
• cout << “\n the size of a Drug record is “ << sizeof(Drug);
• int n = endpos/ sizeof(drug)
• cout << “\n” << n << “drug records are in the the file”;
}
•Page 327
Random Access – Querying a File
• void main( )
• {
• drug drugobj;
• fstream ifile(“drugs.dat”, ios::in);
• ifile.seekg(0, ios::end);
• long endpos = ifile.tellg( );
•Page 328
Random Access – Querying a File
•Page 329
Formatted I/O - ios format functions
• By default console I/O is unformatted, but using following
ios functions, we can format them:
setf() Sets format flags that can control the form of
output display.
unsetf() Resets format flags.
width() Sets the required field size for displaying
output.
fill() Sets the padding used to fill unused portions
of a field.
precision() Sets the number of digits to be displayed after
the decimal point of a float value.
•Page 330
Format flags
Format required Flag Bit-field
(arg1) (arg2)
Left-justified output ios::left ios::adjustfield
Right-justified output ios::right ios::adjustfield
•Page 331
Manipulators
• setw (int w) Set the field width to w.
•Page 332
Summary
•Page 333
Templates
•Page 334
Objectives
•Page 335
Template Functions
•Page 336
Template Functions
•Page 337
Template Functions
•Page 338
Template Functions
•Page 339
Template Functions - Implementation
void main()
#include <iostream.h> {
template <class T> int x=10,y=20;
void swap(T &a, T &b) swap(x,y);
{ cout<<x<<" "<<y<<endl;
T temp=a; char *s1="Hello",*s2="Hi";
a=b; swap(s1,s2);
b=temp; cout<<s1<<" "<<s2<<endl;
}
}
•Page 340
Multiple Generic Types
template<class T, class S, class Z>
void fun(T a, S b, Z c)
{
cout<<a<<endl<<b<<endl<<c;
}
void main()
{
int i=10;
float j=3.14;
char ch=‘A’;
fun (i, j, ch);
}
•Page 341
Explicitly Overloading a Generic Function
•Page 342
Explicitly Overloading a Generic Function
• // Overriding a template function
• #include <iostream>
• using namespace std;
• template <class X> void swapargs (X &a, X &b)
• {X temp;
• temp = a;
• a = b;
• b = temp;
• cout << “Inside template swapargs \n”; }
•Page 343
Explicitly Overloading a Generic Function
• Int main( )
• {int i = 10, j = 20;
• double x = 10.1, y = 23.3;
• char a = ‘x’, b = ‘z’;
• cout << “Original i, j: “ << i << “ “ << j << ‘\n’;
• cout << “Original x, y: “ << x << “ “ << y << ‘\n’;
• cout << “Original a, b: “ << a << “ “ << b << ‘\n’;
• swapargs( i, j); // calls explicitly overloaded swapargs
• swapargs( x, y); // calls generic swapargs
• swapargs( a, b); // calls generic swapargs
• cout << “Swapped i, j: “ << i << “ “ << j << ‘\n’;
• cout << “Swapped x, y: “ << x << “ “ << y << ‘\n’;
• cout << “Swapped a, b: “ << a << “ “ << b << ‘\n’;
• return 0; }
•Page 344
Overloading a Template Function
•Page 345
Overloading a Template Function
• Int main( )
• {
• f(10); // calls f( X)
• f( 10, 20); // calls f( X, Y)
• return 0;
• }
•Page 346
Templates Vs Macros
•Page 347
Template Classes
• Generic classes are useful when a class uses logic that can
be generalized.
•Page 348
Template Classes
•Page 349
Template Classes
• Member functions of a generic class are themselves automatically
generic. You need not use the keyword template to explicitly specify
them as such.
•Page 350
Template Classes
• public:
• stack( )
• { tos = 0; // initialize stack }
• void push( StackType ob); // push object on stack
• StackType pop( ); // pop object from stack };
•Page 351
Template Classes
• int main( )
• {
• //demonstrating character stacks
• stack<char> s1, s2; // create two character stacks
• int i;
• s1.push( ‘a’);
• s2.push( ‘x’);
• s1.push( ‘b’);
• s2.push( ‘y’);
• s1.push( ‘c’);
• s2.push( ‘z’);
• for (int i = 0; i < 3; i+ +) cout << “pop s1: “ << s1.pop( ) << “\n”;
• for (int i = 0; i < 3; i+ +) cout << “pop s2: “ << s2.pop( ) << “\n”;
•Page 352
Template Classes
•Page 353
Template Class
•Page 354
Inheritence and Template class
•Page 355
Inheritence and Template class
Example :Template class to template class
template<class type>
template<class type>
class base class Der:public base<type>
{ { main()
type x; type y; {
public: public: Der<int> obj;
void getx() obj.getx();
void gety()
{ cin>>x; } obj.putx();
{cin>>y;}
void putx() obj.gety();
{cout<<x; } void puty() obj.puty();
}; {cout<<y; } }
};
•Page 356
Inheritence and Template class
Example :Template class to normal class
class Der:public base<int>
template<class type> main()
class base {
{
{ int y;
type x; Der obj;
public:
public: obj.getx();
void gety()
void getx() obj.putx();
{cin>>y;}
{ cin>>x; } obj.gety();
obj.puty();
void putx() void puty()
}
{cout<<x; } {cout<<y; }
}; };
•Page 357
Inheritence and Template class
Example :Normal class to Template class
template<class type>
class base main()
{ class Der:public base
{
int x; {
public: Der<int> obj;
type y;
void getx() obj.getx();
public:
{ cin>>x; } obj.putx();
void gety()
obj.gety();
void putx() {cin>>y;}
obj.puty();
{cout<<x; }
}
}; void puty()
{cout<<y; }
};
•Page 358
Standard Template Library (STL)
•Page 359
Containers
•Page 360
Containers cont..
• Sequence containers
– Vector , deque , list
• Associative containers
– Set ,multiset ,map ,multimap
• Container adapters
– Stack ,queue ,priority_queue
•Page 361
Common STL Member Functions
•Page 362
Iterators
•Page 363
Types of Iterators
• Input
– Retrieval of elements from container , can only move forward
• Output
– Used for storing elements to container, forward
• Forward
– Combines input and output
• Bidirectional
– Like forward, but can move backwards as well
• Random access
– Like bidirectional, but can also jump to any element
•Page 364
Iterator Operations
•Page 365
Iterator Operations cont..
• Bidirectional iterator
– --p, p--
• Random access iterator
– p + i, p += i
– p - i, p -= i
– p[i]
– p < p1, p <= p1
– p > p1, p >= p1
•Page 366
Basic Steps to Use STL
•Page 367
Example : Vector container
• Vector
– Have to include the following header file <vector>
– Data structure with contiguous memory locations
• Access elements with []
– Use when data must be sorted and easily accessible
•Page 368
Vector container operations
•Page 369
Vector container operations cont..
– erase( iterator )
• Remove element from container
– erase( iter1, iter2 )
• Will give a range to delete between iter1 to iter2
– clear()
• Will erase the entire vector.
– begin()
• Will return the iterator to the beginning.
– end()
• Will return the iterator to the end of vector.
•Page 370
Summary
•Page 371
Exception Handling
•Page 372
Objectives
•Page 373
What is an Exception?
•Page 374
Common Exceptions
•Page 375
Exception Handling
•Page 376
Error handling in C
•Page 378
Exception Handling - Mechanics
•Page 379
The throw Statement
•Page 380
Uncaught Exceptions
•Page 381
Restricting Exceptions
•Page 382
Restricting Exceptions
•Page 383
Catching Any Exception
•Page 384
Re-throwing an exception
•Page 385
Handling Derived Class Exceptions
catch( CBaseException& ex )
{
// handle a base type of exception
}
catch( CDerivedException& ex )
{
// this handler would never “run” because its
// base would catch everything it would…
}
•Page 386
Standard Library Exception Hierarchy
Exception
logic_error runtime_error
bad_alloc bad_cast
range_error
domain_error bad_exception bad_typeid
length_error overflow_error
ios_base::failure
out_of_range underflow_error
invalid_argument
•Page 387
Standard Library Exceptions
• Declares many std exception objects, e.g. :
bad_alloc, thrown when new fails
bad_cast, thrown when dynamic_cast fails
bad_typeid, thrown if dynamic_cast is applied to a NULL pointer
bad_exception, thrown when an unexpected (non-specified) exception
is thrown
• also in std namespace
– throw std::range_error;
•Page 388
Programming With Exceptions
Avoid exceptions :
– for asynchronous events.
– for ordinary error conditions.
– for flow-of-control.
•Page 389
Summary
•Page 390
Run Time Type Identification
(RTTI)
•Page 391
Objectives
•Page 392
RTTI
•Page 393
What is RTTI?
•Page 394
RTTI
• RTTI is possible only with virtual functions and base class
pointers. While using virtual functions, you must have
access to the base class source code.
• At such times you should use RTTI. You can derive a new
class from the base class and add your extra member
function to it.
• Then, you can detect your particular type (using RTTI) and
call the member function.
•Page 395
C++ RTTI support
•Page 396
The type_info class
•Page 397
A Simple Application of RTTI
• #include<iostream>
• using namespace std;
• class Figure
• {public:
• virtual void draw( ) = 0; };
•Page 398
A Simple Application of RTTI
• Class Triangle : Public Figure
• {
• public:
• void draw( )
• { cout “Triangle’s draw\n”; } };
• Figure* factory( ) // a factory for objects derived from Figure
• {switch( rand( ) % 3)
• {case 0 : return new Rectangle;
• case 1 : return new Circle;
• case 2 : return new Triangle; }}
• int main( )
• {
• Figure *ptr; // pointer to base class
• int i;
•Page 399
A Simple Application of RTTI
• int r, c, t;
• for (i = 0; i < 10, i + +) // generate and count objects
• {ptr = factory( ); // generate an object
• cout << “Object is “ << typeid(*ptr).name( ) << endl;
• if (typeid(*ptr) == typeid(Rectangle) r++;
• if (typeid(*ptr) == typeid(Circle) c++;
• if (typeid(*ptr) == typeid(Triangle) t++; }
• cout << “figures generated:\n”;
• cout << “rectangles: “ << r << endl;
• cout << “circles: “ << c << endl;
• cout << “triangles: “ << t << endl;
• return 0;
• }
•Page 400
The dynamic_cast Operator
•Page 401
The dynamic_cast Operator
•Page 402
Dynamic_cast -example
bp=&bobj;
dp= dynamic_cast<Derived *> (bp);
if (!dp) cout<<“Cast fails”;
•Page 403
Summary
•Page 404
Namespaces
•Page 405
Objectives
•Page 406
Namespaces – An Introduction
•Page 407
Namespaces – An Introduction
•Page 408
Namespace Basics
•Page 409
Namespace – An Example
• namespace CounterNameSpace
• {int upperbound;
• int lowerbound;
• class counter
• {int count;
• public:
• counter (int n)
• {if (n <= upperbound)
• count = n;
• else
• count = upperbound; }
• void reset ( int n)
• {if (n <= upperbound)
• count = n; }
•Page 410
Namespace – An Example
• int run( )
• {if (count > lowerbound)
• return count--;
• else
• return lowerbound; } }; // end of class
• } // end of namespace
•Page 411
Namespace – An Example
•Page 412
Namespace – Additional Points
• Syntax is similar to that of a class.
• Definition can only appear at the global scope.
• Declarations that fall outside all namespaces are still
members of global namespace.
• Alternative names can be given called namespace-
alias.
• Members of a namespace may be defined within or
outside the namespace.
• Definition can be nested within another namespace
definition.
•Page 413
Using a Namespace
•Page 414
Unnamed Namespaces
• Allows you to create identifiers unique within a file.
•Page 415
The New C++ header
•Page 416
Summary
•Page 417