COMP 345 - Advanced Program Design with C++
1
ADVANCED PROGRAM DESIGN
WITH C++
Virtual functions
Slicing problem
Polymorphism
Concordia University
Abstract classes
Function pointers
Virtual functions tables
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
2
Polymorphism
• Polymorphism
• Associating many meanings to one function.
• Virtual functions provide this capability.
• Fundamental principle of object-oriented programming.
• Virtual
• Existing in "essence" though not in fact.
• Virtual functions.
• Virtual (abstract) classes.
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
3
Polymorphism
• Best explained by example:
• Classes for several kinds of figures
• Rectangles, circles, etc.
• Each figure is an object of a different class
• Each have different data elements and formulas to compute them
• Rectangle data: name, area, perimeter, height, width
• Circle data: name, area, perimeter, radius
• All derive from one parent-class: CShape
• Requires a method getArea()
• Different formula to compute different figures’ area, requires different
implementation for each kind of figure
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
4
Polymorphism
• Each class needs a different getArea() function
• Can define a member getArea() in each class, so:
CRectangle r;
CCircle c;
r.getArea(); //Calls Rectangle’s getArea
c.getArea(); //Calls Circle’s getArea
• Nothing new here yet…
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
5
Polymorphism
• Problem!
• Parent class Figure may contain functions that applies to all kinds of figures.
• Consider: print() : prints out all characteristics common to all kinds of
figures
• Fine for getName(), as it has common behavior.
• However, getArea()has subclass-specific behavior
• Complications!
• Which getArea() function to call?
• From which class?
• Here, a function that exposes common behavior uses another function that
exposes subclass-specific behavior.
• May hardcode a function that calls the right getArea() depending on which
subclass the figure in question is.
• Need a mechanism to call subclass-specific behavior automatically
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
6
Polymorphism
• Problem!
• Consider a new kind of figure later coming along: CTriangle class derived
from CShape class
• Function print() inherited from CShape
• Will it work for triangles?
• It uses getArea(), which is different for each subclass of figure
• It will use CShape::getArea(), which was not made to work for triangles
• We want the inherited function center() to use the function
Triangle::getArea() and not the function CShape::getArea()
• But class CTriangle wasn’t even written when CShape::print() was
written. It does not “know” about triangles.
• If print() is hard-coded to call the right getArea() depending on the type of
CShape, we need to change the implementation of print()every time we add a
new subclass of Cshape.
• Again, we need a mechanism to automatically call subtype-specific behavior.
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
7
Polymorphism
void displayCShapeDynamicCastDemo(CShape& shape)
{
CShape*
p = &shape;
CCircle*
p1 = dynamic_cast<CCircle*>(p);
CRectangle* p2 = dynamic_cast<CRectangle*>(p);
CTriangle* p3 = dynamic_cast<CTriangle*>(p);
if (p1
cout
cout
}
if (p2
cout
cout
cout
}
if (p3
cout
cout
cout
}
!= NULL){
<< "Circle's area is "
<< "Circle's radius is "
<< p1->getArea()
<< endl;
<< p1->getRadius() << endl;
!=
<<
<<
<<
NULL){
"Rectangle's area is "
<< p2->getArea()
<< endl;
"Rectangle's width is " << p2->getWidth() << endl;
"Rectangle's height is " << p2->getLength() << endl;
!=
<<
<<
<<
NULL){
"Triangle's area is "
"Triangle's width is "
"Triangle's height is "
<< p3->getArea()
<< endl;
<< p3->getHeight() << endl;
<< p3->getBase()
<< endl;
}
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
8
Polymorphism: virtual methods
• Virtual methods allow to declare
such a subtype-specific behavior.
• If an object of type CShape is
declared and instantiated with an
object of type e.g. CRectangle,
calling any of its virtual methods
will result in using CRectangle’s
behavior, even though its type is
declared as CShape.
• This requires a dynamic run-time
binding mechanism. In C++
implementation, it is called
“dynamic binding” or “late
binding”.
Concordia University
class CShape{
protected:
double area;
string name;
public:
CShape() : name("anonymous"){
}
CShape(string newName) : name(newName){
}
string getName(){
return name;
}
virtual double getArea()= 0;
virtual void print(){
cout << "Shape:" << name << endl;
cout << "Area: " << getArea() << endl;
}
};
bool operator < (CShape &s1, CShape &s2){
return (s1.getArea() < s2.getArea());
}
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
9
Polymorphism: virtual methods
• Polymorphic behavior comes when you declare an object of a base class type and
then instantiate it with an instance of a derived type.
• In this case, the type of the object can only be determined dynamically at runtime.
• If a method is declared as virtual, its subtype behavior is branched upon.
• If a method is not declared as virtual, the base type behavior is branched
upon. void main()
{
CRectangle *shapeRect = new CRectangle("shapeRect", 16.8, 8.8);
CCircle *shapeCircle = new CCircle("shapeCircle", 13.8);
CTriangle *shapeTriangle = new CTriangle("shapeTriangle", 2.5, 3.8);
CShape *shapes[] = { shapeRect, shapeCircle, shapeTriangle };
for (int i = 0; i < sizeof(shapes) / sizeof(shapes[0]); i++){
shapes[i]->getArea();
shapes[i]->print();
if (i>0)
cout << "Shape[" << i << "] area (" << shapes[i]->getArea()
<< ") less than Shape[" << i - 1 << "] area ("
<< shapes[i-1]->getArea() << ") : "
<< (*shapes[i] < *shapes[i-1]) << endl;
}
delete shapeRect;
delete shapeCircle;
delete shapeTriangle;
}
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
10
Virtual methods
class CCircle : public CShape{
double radius;
public:
CCircle() :
CShape(), radius(1){
};
CCircle(string n, double r) :
CShape(n), radius(r) {
};
void setRadius(double r) {
radius = r; }
double getRadius() const {
return radius; }
double getArea(){
area = 3.14159265 * radius * radius;
return area;
}
void print(){
CShape::print();
cout << "Circle:" << endl;
cout << "Radius: " << radius << endl;
}
};
Concordia University
class CRectangle : public CShape{
double length;
double width;
public:
CRectangle() :
CShape(), length(1), width(1){
}
CRectangle(string n, double l, double w) :
CShape(n), length(l), width(w){
}
void setLength(double l) {
length = l; }
void setWidth(double w) {
width = w; }
double getLength() const {
return length; }
double getWidth() const {
return width; }
double getArea(){
area = length * width;
return area;
}
void print(){
CShape::print();
cout << "Rectangle:" << endl;
cout << "Height: " << length <<
" Width: " << width << endl;
}
};
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
11
Polymorphism: pure virtual methods and abstract classes
• In C++, some virtual methods can be declared as “pure virtual”.
• Any class with at least one pure virtual method is an abstract class.
• No instance of an abstract class can be created.
• However, an abstract class still represents a data type.
• To be used, abstract classes need to be derived by subclasses that
provide an implementation to all their pure virtual methods.
• A class that derives an abstract class and does not provide an
implementation for all the pure virtual functions it inherits is itself
still an abstract class.
• Contrary to Java interfaces, C++ abstract classes can provide a
definition for some of their methods, and can have non-constant
data members.
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
12
Polymorphism: pure virtual methods and abstract classes
• There are two main uses for pure virtual functions/abstract classes:
• Classes that are to be used polymorphically with different subclass behaviors.
• Interfaces, i.e. classes that contain only pure virtual functions. This is
equivalent to Java’s interfaces.
class CShape{
protected:
double area;
string name;
public:
CShape() : name("anonymous"){
}
CShape(string newName) : name(newName){
}
string getName(){
return name;
}
virtual double getArea()= 0;
virtual void print(){
cout << "Shape:" << name << endl;
cout << "Area: " << getArea() << endl;
}
};
Concordia University
class Iserialisable {
public:
virtual void load(istream& in) = 0;
virtual void save(ostream& out) = 0;
virtual ~serialisable();
}
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
13
Virtual destructors
• If you implement a class to be used polymorphically, you probably
need to declare its destructor as virtual.
• If an object of a derived class is assigned to a pointer to a base
class, and then later deleted using the base class pointer, the base
class destructor will be used to delete the object.
• The derived class’ destructor will
thus never be called, possibly
leading to a resource leak.
• Rule of thumb: always declare the
destructor as virtual if a class is to
be use polymorphically.
class Base {
public:
virtual ~Base(){
cout << "Base::~Base()" << endl;
}
};
class Derived : public Base {
public:
~Derived(){
cout << "Derived::~Derived()" << endl;
}
};
int main(){
Base *b = new Derived();
delete b;
int i; cin >> i;
}
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
COMP 345 - Advanced Program Design with C++
14
References
• Mark Radford. C++ Interface Classes - An Introduction. Overload Journal #62 -
Aug 2004.
Concordia University
Department of Computer Science and Software Engineering
Joey Paquet, 2007-2014
© Copyright 2026 Paperzz