J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming Polymorphism
Problems with switch statement
¾ Programmer may forget to test all possible cases in a switch.
¾ Tracking this down can be time consuming and error prone Solution - use virtual functions (polymorphism)
¾ Virtual functions and polymorphic programming can eliminate the need for switch
¾ Design and implement systems that are more easily extensible
¾ Programs written to generically process objects of all existing classes in a hierarchy
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming
Polymorphism
¾Ability for objects of different classes to respond differently to the same function call
¾Base-class pointer (or reference) calls a virtual function - C++ chooses the correct overridden function in object
Dynamic binding (late binding ) as opposite to early (static) binding
¾Object's type not needed when compiling virtual functions
¾Accommodate new classes that have been added after compilation
¾Important for ISV’s (Independent Software Vendors) who do not wish to reveal source code to their customers
Object Oriented Programming Virtual functions
¾ The keyword virtual is a function specifier that provides a mechanism to dynamically select at runtime the appropriate member function from among base and derived class functions (polymorphism=many forms ).
¾ A base-class pointer (reference) to a derived class object will call the correct draw function
¾ If a derived class does not define a virtual function it is inherited from the base class
¾ There are two types of virtual functions:
¾virtual double area(); // normal virtual
¾virtual double area() =0; // pure virtual
J. Kwiatkowski, Wrocław University. of Technology
An example
classInstrument { public:
void play()const {cout<< "Instrument::play"<<endl; } char* what()const{return"Instrument"; } };
classWind :publicInstrument { public:
void play()const{cout<< ”Wind::play"<<endl; } char* what()const{return”Wind"; } };
voidgo(Instrument& i) {
i.play(); // binding during compilation } ...
Instrument instrument;
Wind wind;
go(instrument); // „play” from class Instrument – not surprising go(wind); // „play” from class Instrument – why ?
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming An example
Now using virtual function classInstrument {
public:
virtual void play()const {cout<< "Instrument::graj"<<endl; } virtual char* what()const{return"Instrument"; } };
classWind :publicInstrument { public:
void play()const{cout<< ”Wind::play"<<endl; } char* what()const{return”Wind"; } };
voidgo(Instrument& i) { i.play();
}
Object Oriented Programming An example
Using pointers Instrument instrument;
Wind ourwind;
Instrument *demo;
demo= &instrument;
demo->play(); // „play” from class Instrument demo = &ourwind;
demo->play(); // „play” from class Wind
Using reference Instrument instrument;
Wind ourwind;
Instrument &demo1 = instrument;
demo1.play(); // „play” from class Instrument Instrument &demo2 = ourwind;
demo2.play(); // „play” from class Wind
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming VTABLE
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming Small problem
¾Access specifier from class for which pointer is defined is used
class basic { public:
virtual void fun( ); };
class derived : public basic { virtual void fun( ); }
basic *pointer1;
derived *pointer2;
pointer1->fun( ); // O.K.
pointer2->fun( ); // ?
Object Oriented Programming Collection
class Point { ...
public:
virtual void draw();
};
class Circle: public Point { ...
public:
virtual void draw();
};
class Collection { protected:
Point ** arr;
int size;
public:
Collection(int n);
void draw()
void insert (Point *p, int i);
};
void Collection:draw() { for(int i=0;i<size;i++)
if (arr[i] != 0) arr[i] -> draw();
}
J. Kwiatkowski, Wrocław University. of Technology
Abstract classes
¾ A pure virtual function is one whose body is undefined.
virtual void printName() = 0;
¾ derived classes must implement the pure virtual functions (else they will be abstract too!)
¾ A pure virtual function is used to defer the implementation decision of the function.
¾ A class that has at least one pure virtual function is called an abstract class (normal classes are sometimes called concrete classes).
¾ Abstraction is just a design mechanism - a way of deferring design decisions.
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming Abstract classes
¾Typically: the base class in a hierarchy of classes is an abstract class. (Its only there to help the designer start the hierarchy - an abstract class might often contain some data declarations and maybe some methods, but it is never intended to actually be instantiated)
¾An abstract class cannot be used to declare objects
(cannot be instantiated).¾An abstract class can be used to declare pointers that can access objects derived from the abstract base class.
Object Oriented Programming Abstract classes
//definition of the abstract base class class TwoD { //this is an abstract class
public:
virtual double area() const { return 0.0; } //pure virtual member function
virtual void printName()const = 0;
};
By having any pure virtual member function, this class is declared as abstract.
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming Virtual - constructors and destructors ?
¾ Constructors are always dynamic (don’t need virtual.)
¾ Destructors should be declared virtual (if you delete a derived class through a base pointer.)
¾ There can be significant problems if you don’t declare destructors virtual and you try to delete through the base pointer. (The wrong memory can be freed up if your classes use malloc or new etc ) We will return to this issue.
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming Overloading & virtual functions
Virtual functions provide another way to overload names, and hence another way to provide a form of polymorphism.
The same types Binding
Overloaded functions never Compilation time
Virtual functions always runtime
Object Oriented Programming Summary
¾ A pure virtual function is a function whose body is undefined.
¾ A class having a pure virtual member function is an abstract class.
¾ An abstract base class defines the interface for its derived classes but cannot itself be used to declare objects.
¾ Polymorphism - the ability for objects of different classes related by inheritance to respond differently to the same message (function call).
¾ We can use more elaborate combinations of the access modifier when deriving classes from base classes.
J. Kwiatkowski, Wrocław University. of Technology
Case study
Abstract class class Shape {
public:
virtual double area() const { return 0.0; } virtual double volume() const { return 0.0; } // pure virtual functions overridden in derived classes
virtual void printShapeName() const = 0;
virtual void print() const = 0;
};
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming
Case study Class Point
class Point : public Shape { public:
Point( int = 0, int = 0 ); // default constructor void setPoint( int, int );
int getX() const { return x; } int getY() const { return y; } virtual void printShapeName() const
{ cout << "Point: "; }
virtual void print() const;
private:
int x, y; // x and y coordinates of Point };
Object Oriented Programming Case study
Point::Point( int a, int b ) { setPoint( a, b ); } void Point::setPoint( int a, int b )
{ x = a;
y = b;
}
void Point::print() const
{ cout << '[' << x << ", " << y << ']'; }
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming
Case study Class Circle
class Circle : public Point { public:
Circle( double r = 0.0, int x = 0, int y = 0 );
void setRadius( double );
double getRadius() const;
virtual double area() const;
virtual void printShapeName() const { cout << "Circle: "; } virtual void print() const;
private:
double radius; // radius of Circle };
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming Case study
Circle::Circle( double r, int a, int b )
: Point( a, b ) // call base-class constructor { setRadius( r ); }
void Circle::setRadius( double r ) { radius = r > 0 ? r : 0; } double Circle::getRadius() const { return radius; } double Circle::area() const
{ return 3.14159 * radius * radius; } void Circle::print() const
{
Point::print();
cout << "; Radius = " << radius;
}
Object Oriented Programming Case study
Class Cylinder
class Cylinder : public Circle { public:
// default constructor
Cylinder( double h = 0.0, double r = 0.0, int x = 0, int y = 0 );
void setHeight( double );
double getHeight();
virtual double area() const;
virtual double volume() const;
virtual void printShapeName() const { cout << "Cylinder: "; } virtual void print() const;
private:
double height; // height of Cylinder };
J. Kwiatkowski, Wrocław University. of Technology
Case study Cylinder::Cylinder( double h, double r, int x, int y )
: Circle( r, x, y ) // call base-class constructor { setHeight( h ); }
void Cylinder::setHeight( double h ) { height = h > 0 ? h : 0; }
double Cylinder::getHeight() { return height; } double Cylinder::area() const
{
// surface area of Cylinder return 2 * Circle::area() +
2 * 3.14159 * getRadius() * height;
}
J. Kwiatkowski, Wrocław University. of Technology
Object Oriented Programming Case study
double Cylinder::volume() const { return Circle::area() * height; } void Cylinder::print() const
{
Circle::print();
cout << "; Height = " << height;
}