Polymorph Is M
Polymorph Is M
1
Polymorphism
2
Polymorphism
• It enables to write programs that process
objects of classes (that are part of the same
class hierarchy) as if they are all objects of the
hierarchy's base class.
base class
3
Polymorphism – Example 1
• Program that simulates the movement of several
types of animals
– Classes Fish, Frog and Bird
– Each of these classes inherits from base class Animal
• contains a function move and maintains an animal's
current location
– Each derived class implements function move
– Program maintains an array of pointers to objects of the
various derived classes (Fish, Frog and Bird )
– To simulate the animal’s movements, the program
sends each object the same message, move()
4
Cont.
– Each object knows how to modify its location
appropriately for its specific type of movement
– Relying on each object to know how to "do the
right thing" in response to the same function call
is the key concept of polymorphism
animal
5
Polymorphism – Example 2
• Suppose you have a objects of different
classes
• All are inherited from a base class
• you want to put them all in an array
• perform a particular operation on them using the
same function call.
Shape
7
Cont.
• This is an amazing capability:
– Completely different functions are executed by the
same function call.
– If the pointer in ptrarray points to a circle, the
function that draws a circle is called
– if it points to a triangle, the triangle-drawing
function is called.
This is called polymorphism, which means
different forms
8
Condition for polymorphism
• Following condition must be meet in order to
achieve polymorphic behaviour
– First, all the different classes of shapes, such as
circle and triangles, must be inherited from a
single base class
– Second, the draw() function must be declared to
be virtual in the base class.
Shape
draw()
ptrarr[j]->draw();
Circle Square Triangle
draw() draw() draw()
9
Example programs
• Normal Member Functions Accessed with
Pointers
• Virtual Member Functions Accessed with
Pointers
10
Normal Member Functions Accessed
class Base { main() { *ptr
public: Derv1 dv1;
void show() Derv2 dv2;
{ cout << “Base\n”; } Base* ptr;
}; ptr = &dv1; dv1 dv2
class Derv1 : public Base { ptr->show();
public: ptr = &dv2; Program Output
void show() ptr->show();
{ cout << “Derv1\n”; } } Base
}; Go to program Base
class Derv2 : public Base {
public: Note: Compiler ignores the
void show() contents of the pointer ptr and
{ cout << “Derv2\n”; } chooses the member function that
}; matches the type of the pointer 11
Non-virtual pointer access.
12
Virtual Member Functions Accessed
class Base { main() { *ptr
public: Derv1 dv1;
virtual void show() Derv2 dv2;
{ cout << “Base\n”; } Base* ptr;
}; ptr = &dv1; dv1 dv2
class Derv1 : public Base { ptr->show();
public: ptr = &dv2; Program Output
void show() ptr->show();
{ cout << “Derv1\n”; } } Derv1
}; Go to program Derv2
class Derv2 : public Base {
public: Note: Compiler selects the function
void show() based on the contents of the
{ cout << “Derv2\n”; } pointer ptr, not on the type of the
}; pointer 13
Virtual pointer access
14
Static binding
• When a member function is called with the object of that class
• Function invocation is resolved at compile time.
• This is called static or early binding
• This is not a polymorphic behavior
15
Dynamic binding
• Virtual function can be invoked using base
class pointer to a derive class object
– basePtr—>draw()
• Now the correct derived class draw function
will be selected dynamically (execution time)
• This is called dynamic or late binding
• At run time, when it knows what class is
pointed by basePtr, the show() function of
that class is called
16
Allowable assignments b/w base and derived class object and pointer
17
Abstract Classes and Pure Virtual Functions
class Base {
Pure virtual
public: Go to program
virtual void show() = 0; function
}; 0 1
class Derv1 : public Base { main() { arr[2]
public: Base* arr[2];
void show() Derv1 dv1;
{ cout << “Derv1\n”; } Derv2 dv2;
}; arr[0] = &dv1;
dv1 dv2
class Derv2 : public Base { arr[1] = &dv2;
public: arr[0]->show(); Program Output
void show() arr[1]->show(); Derv1
{ cout << “Derv2\n”; } // Base b; Derv2
}; }
Note: objects of abstract class cannot be created 18
Note
• After aiming a base-class pointer at a derived-
class object, attempting to reference derived-
class-only members with the base-class
pointer is a compilation error
class B { class Derv1 : public B { main(){
public: public: B *ptr;
virtual void show() = 0; void show() Derv1 dv1;
}; { cout << “Derv1\n”; } ptr = &dv1;
void display() ptr—>show();
{cout<<“hello derv1”; } ptr—>display();
}; }
19
Example program: Person class
class person { class professor : public person {
protected: private:
char name[40]; int numPubs;
public: public:
void getName() { void getData() {
cout << “ Enter name: “; person::getName();
cin >> name; cout << “ Enter publications: “;
} cin >> numPubs;
void putName() { }
cout << “Name is: “ << name; bool isOutstanding() {
} return (numPubs > 100) ? true :
virtual void getData() = 0; false;
virtual bool isOutstanding() = 0; }
}; };
20
Cont.
class student : public person { person* persPtr[100];
private: int n =0;
float gpa; persPtr[n] = new student;
public: persPtr[n]->getData();
void getData() { n++;
person::getName(); persPtr[n] = new professor;
cout << “ Enter GPA: “; persPtr[n]->getData();
cin >> gpa; n++;
} for(int j=0; j<n; j++){
bool isOutstanding() { persPtr[j]->putName();
return (gpa > 3.5) ? true : false; if( persPtr[j]->isOutstanding() )
} cout << “ This person is
}; outstanding\n”;
}
Go to program 21
Virtual Destructors
• A problem can occur when using
polymorphism to process dynamically
allocated objects of a class hierarchy
• E.g. applying delete operator to a base class
pointer, which point to derived class objects
– B *ptr;
– Derv1 dv1;
– ptr = &dv1;
– delete ptr;
• Solution : virtual destructor
22
Cont.
• A virtual destructor in base class makes all
derived class destructor virtual
– B *ptr; Derv1 dv1;
– ptr = &dv1;
– delete ptr;
• Now destructor for appropriate class is called
• When derived class object is destroyed, base
class part of derive class object is also destroyed
• Base class destructor is executed after derived
class destructor
23
Example – virtual destructor
class Base { Without virtual Destructor
public: *pBase Object of
virtual ~Base() Derv
{ cout << “Base Object of
destroyed\n”; } Derv
}; Program Output
class Derv : public Base { Base destroyed
public:
~Derv() With virtual Destructor
{ cout << “Derv Object of
destroyed\n”; } *pBase
Derv
};
main() { Program Output
Base* pBase = new Derv; Derv destroyed
delete pBase; Base destroyed
} Go to program 24
Virtual base classes
• A problem can arise if a member function in
the Grandchild class wants to access data or
functions in the Parent class
When the Child1 and
Child2 classes are
derived from Parent,
each inherits a copy of
Parent; this copy is
called a subobject
25
Cont.
class Parent {
protected: basedata
int basedata;
};
class Child1 : public Parent
{ };
class Child2 : public Parent basedata basedata
{ };
class Grandchild : public Child1,
public Child2 {
public: basedata
int getdata()
{ return basedata; }
}; This situation is ambiguous, and
that’s what the compiler reports
26
Cont.
class Parent { keyword virtual in these
protected: two classes causes them
int basedata; to share a single common
}; subobject of their base
class Child1 : virtual public Parent class Parent
{ };
class Child2 : virtual public Parent
{ };
class Grandchild : public Child1, Go to program
public Child2 {
public:
int getdata()
{ return basedata; }
};
27