CS1004 – Object
Oriented Programming
Lecture # 24
Monday, May 16, 2022
Spring 2022
FAST – NUCES, Faisalabad Campus
Muhammad Yousaf
2 Today’s Lecture
Polymorphism in C++
Pointers to derived classes
Introduction to virtual functions
CS1004 - Objected Oriented Programming
Review — Accessing Members of
3 Base and Derived Classes
Access to members of a class object is determined by
the type of the handle.
Definition: Handle
The thing by which the members of an object are accessed
May be
An object name (i.e., variable, etc.)
A reference to an object
A pointer to an object
CS1004 - Objected Oriented Programming
Review — Accessing Members of
4 Base and Derived Classes (continued)
This is referred to as static binding
i.e., the binding between handles and members is
determined at compile time
i.e., statically
CS1004 - Objected Oriented Programming
5 What if we need Dynamic Binding?
What if we need a class in which class Rectangle : public Shape {
access to methods is determined at public:
run time by the type of the object,
not the type of the handle void Rotate();
void Draw();
class Shape {
...
public: }
void Rotate();
void Draw(); class Ellipse : public Shape {
d to
o public:
... m eth ct
s the obje void Rotate();
} c c es nd o f
to a
h t ki l e!
void Draw();
d i g n d
Nee the r of ha ...
w
d r a r d l es s }
e g a
R
CS1004 - Objected Oriented Programming
6 Solution – Virtual Functions
Define a method as virtual, and the subclass
method overrides the base class method
For example
class Shape { This tells the compiler to add
public: internal pointers to every object
virtual void Rotate(); of class Shape and its derived
classes, so that pointers to
virtual void Draw();
correct methods can be stored
... with each object.
}
CS1004 - Objected Oriented Programming
7 What if we need Dynamic Binding?
class Shape { class Rectangle : public Shape {
public: public:
virtual void Rotate(); void Rotate();
virtual void Draw(); void Draw();
... ...
} }
class Ellipse : public Shape {
Subclass methods override the base public:
class methods
void Rotate();
(if specified) void Draw();
C++ dynamically chooses the correct ...
method for the class from which the }
object was instantiated
CS1004 - Objected Oriented Programming
8 Notes on virtual
If a method is declared virtual in a class,
… it is automatically virtual in all derived classes
It is a really, really good idea to make destructors
virtual!
virtual ~Shape();
Reason: to invoke the correct destructor, no matter how
object is accessed
CS1004 - Objected Oriented Programming
9 Virtual Destructors
Constructors cannot be virtual, but destructors can
be virtual
It ensures that the derived class destructor is called
when a base class pointer is used while deleting a
dynamically created derived class object
CS1004 - Objected Oriented Programming
10 Virtual Destructors (contd.)
#include <iostream> int main()
using namespace std; {
base *p = new derived;
public: delete p;
~base() { return 0;
cout << "destructing base\ }
n";
} Output:
}; destructing base
class derived : public base {
public:
~derived() {
cout << "destructing
derived\n";
}
}; Using non-virtual destructor
CS1004 - Objected Oriented Programming
11 Virtual Destructors (contd.)
class base { int main()
{
public: base *p = new derived;
virtual ~base() { delete p;
cout << "destructing
base\n"; return 0;
} }
};
Output:
class derived : public base {
destructing derived
public:
destructing base
~derived() {
cout << "destructing
derived\n";
}
};
CS1004 - Objected Oriented Programming
Using virtual destructor
12 Notes on virtual (continued)
A derived class may optionally override a virtual
function
If not, base class method is used
class Shape {
public:
virtual void Rotate();
virtual void Draw();
...
}
class Line : public Shape {
public:
void Rotate(); //Use base class Draw method...
}
CS1004 - Objected Oriented Programming
13 Summary – Based and Derived Class Pointers
Base-class pointer pointing to base-class object
Straightforward
Derived-class pointer pointing to derived-class object
Straightforward
Base-class pointer pointing to derived-class object
Safe
Can access non-virtual methods of only base-class
Can access virtual methods of derived class
Derived-class pointer pointing to base-class object
Compilation error
CS1004 - Objected Oriented Programming
14 Abstract and Concrete Classes
Abstract Classes
Classes from which it is never intended to instantiate any objects
Incomplete—derived classes must define the “missing pieces”
Too generic to define real objects
Normally used as base classes and called abstract base classes
Provide appropriate base class frameworks from which other classes can
inherit
Concrete Classes
Classes used to instantiate objects
Must provide implementation for every member function they define
CS1004 - Objected Oriented Programming
15 Pure virtual Functions
A class is made abstract by declaring one or more of
its virtual functions to be “pure”
By placing "= 0" in its declaration
Example
virtual void draw() const = 0;
" = 0" is known as a pure specifier
Tells compiler that there is no implementation
CS1004 - Objected Oriented Programming
16 Pure virtual Functions (continued)
Every concrete derived class must override all base-
class pure virtual functions
with concrete implementations
If even one pure virtual function is not overridden,
the derived-class will also be abstract
Compiler will refuse to create any objects of the class
Cannot call a constructor
CS1004 - Objected Oriented Programming
17 Purpose
When it does not make sense for base class to have
an implementation of a function
Software design requires all concrete derived
classes to implement the function
Themselves
CS1004 - Objected Oriented Programming
18 Why do we want to do this?
To define a common public interface for various
classes in a class hierarchy
Create framework for abstractions defined in our software
system
The heart of object-oriented programming
Simplifies a lot of big software systems
Enables code re-use in a major way
Readable, maintainable, adaptable code
CS1004 - Objected Oriented Programming
19 Case Study: Payroll System Using Polymorphism
Create a payroll program
Use virtual functions and polymorphism
Problem statement
4 types of employees, paid weekly
Salaried (fixed salary, no matter the hours)
Hourly workers
Commission (paid percentage of sales)
Base-plus-commission (base salary + percentage of sales)
CS1004 - Objected Oriented Programming
20 Case Study: Payroll System Using Polymorphism
Base class Employee
Pure virtual function earnings (returns pay)
Pure virtual because need to know employee type
Cannot calculate for generic employee
Other classes derive from Employee
Employee
SalariedEmployee CommissionEmployee HourlyEmployee
BasePlusCommissionEmployee
CS1004 - Objected Oriented Programming
21 Employee Example
class Employee {
public:
Employee(const char *, const char *);
~Employee();
char *getFirstName() const;
char *getLastName() const;
// Pure virtual functions make Employee abstract base class.
virtual float earnings() const = 0; // pure virtual
virtual void print() const = 0; // pure virtual
protected:
char *firstName;
char *lastName;
};
CS1004 - Objected Oriented Programming
Employee::Employee(const char *first, const char *last)
{
22 firstName = new char[strlen(first) + 1];
strcpy(firstName, first);
lastName = new char[strlen(last) + 1];
strcpy(lastName, last);
}
// Destructor deallocates dynamically allocated memory
Employee::~Employee() {
delete[] firstName;
delete[] lastName;
}
// Return a pointer to the first name
char *Employee::getFirstName() const {
return firstName; // caller must delete memory
}
char *Employee::getLastName() const {
return lastName; // caller must delete memory
}
CS1004 - Objected Oriented Programming
23
class SalariedEmployee : public Employee {
public:
SalariedEmployee(const char *, const char *, float = 0.0);
void setWeeklySalary(float);
virtual float earnings() const;
virtual void print() const;
private:
float weeklySalary;
};
CS1004 - Objected Oriented Programming
// Constructor function for class
24 SalariedEmployee::SalariedEmployee(const char *first,
const char *last, float s)
: Employee(first, last) // call base-class constructor
{
weeklySalary = s > 0 ? s : 0;
}
// Set the SalariedEmployee’s salary
void SalariedEmployee::setWeeklySalary(float s)
{
weeklySalary = s > 0 ? s : 0;
}
// Get the SalariedEmployee’s pay
float SalariedEmployee::earnings() const { return weeklySalary; }
// Print the SalariedEmployee’s name
void SalariedEmployee::print() const
{
cout << endl << " Salaried Employee: " << getFirstName()
<< ' ' << getLastName();
}
CS1004 - Objected Oriented Programming
25
class CommissionWorker : public Employee {
public:
CommissionWorker(const char *, const char *, float = 0.0,
unsigned = 0);
void setCommission(float);
void setQuantity(unsigned);
virtual float earnings() const;
virtual void print() const;
private:
float commission; // amount per item sold
unsigned quantity; // total items sold for week
};
CS1004 - Objected Oriented Programming
CommissionWorker::CommissionWorker(const char *first,
26
const char *last, float c, unsigned q): Employee(first, last) // call base-class
constructor
{
commission = c > 0 ? c : 0;
quantity = q > 0 ? q : 0;
}
void CommissionWorker::setCommission(float c){
commission = c > 0 ? c : 0;
}
void CommissionWorker::setQuantity(unsigned q){
quantity = q > 0 ? q : 0;
}
float CommissionWorker::earnings() const{
return commission * quantity;
}
void CommissionWorker::print() const{
cout << endl << "Commission worker: " << getFirstName()
<< ' ' << getLastName();
}
CS1004 - Objected Oriented Programming
27
class HourlyWorker : public Employee {
public:
HourlyWorker(const char *, const char *, float = 0.0, float =
0.0);
void setWage(float);
void setHours(float);
virtual float earnings() const;
virtual void print() const;
private:
float wage; // wage per hour
float hours; // hours worked for week
};
CS1004 - Objected Oriented Programming
28
HourlyWorker::HourlyWorker(const char *first, const char *last,
float w, float h) : Employee(first, last) // call base-class constructor
{
wage = w > 0 ? w : 0;
hours = h >= 0 && h < 168 ? h : 0;
}
void HourlyWorker::setWage(float w) { wage = w > 0 ? w : 0; }
// Set the hours worked
void HourlyWorker::setHours(float h)
{
hours = h >= 0 && h < 168 ? h : 0;
}
// Get the HourlyWorker's pay
float HourlyWorker::earnings() const { return wage * hours; }
// Print the HourlyWorker's name
void HourlyWorker::print() const
{
cout << endl << " Hourly worker: " << getFirstName()
<< ' ' << getLastName();
}
CS1004 - Objected Oriented Programming
29
BasePlusCommissionEmployee:public CommissionWorker
{
private:
float baseSalary;
public:
BasePlusCommissionEmployee(const char* , const char* , float =0.0,
unsigned =0,float =0.0);
void setBaseSalary(float sal){
baseSalary = sal;
}
float getBaseSalary(void) const {
return baseSalary;
}
void print() const;
float earnings() const;
};
CS1004 - Objected Oriented Programming
30
BasePlusCommissionEmployee::BasePlusCommissionEmployee(const char*
first, const char* last, float c, unsigned q, float
sal) :CommissionWorker(first, last, c, q)
{
baseSalary = (sal);
}
void BasePlusCommissionEmployee::print() const
{
cout << "\nbase-salaried commission employee: ";
CommissionWorker::print(); // code reuse
} // end function print
float BasePlusCommissionEmployee::earnings() const
{
return getBaseSalary() + CommissionWorker::earnings();
} // end function earnings
CS1004 - Objected Oriented Programming
31
int main(void)
{
Employee *ptr; // base-class pointer
SalariedEmployee b("Nauman", "Sarwar", 800.00);
ptr = &b; // base-class pointer to derived-class object
ptr->print(); // dynamic binding
cout << " earned $" << ptr->earnings(); // dynamic binding
b.print(); // static binding
cout << " earned $" << b.earnings(); // static binding
CommissionWorker c("Qasim", “Ali", 3.0, 150);
ptr = &c; // base-class pointer to derived-class object
ptr->print(); // dynamic binding
cout << " earned $" << ptr->earnings(); // dynamic binding
c.print(); // static binding
cout << " earned $" << c.earnings(); // static binding
CS1004 - Objected Oriented Programming
32
BasePlusCommissionEmployee p("Mehshan", "Mustafa", 2.5, 200, 1000.0);
ptr = &p; // base-class pointer to derived-class object
ptr->print(); // dynamic binding
cout << " earned $" << ptr->earnings(); // dynamic binding
p.print(); // static binding
cout << " earned $" << p.earnings(); // static binding
HourlyWorker h("Samer", "Tufail", 13.75, 40);
ptr = &h; // base-class pointer to derived-class object
ptr->print(); // dynamic binding
cout << " earned $" << ptr->earnings(); // dynamic binding
h.print(); // static binding
cout << " earned $" << h.earnings(); // static binding
cout << endl;
return 0;
}
CS1004 - Objected Oriented Programming
33 Output
CS1004 - Objected Oriented Programming
34 Questions
CS1004 - Objected Oriented Programming