Module 31
Intructors: Abir
Das and
Sourangshu
Bhattacharya
Module 31: Programming in C++
Weekly Recap
Objectives & Virtual Function Table
Outline
Staff Salary
Processing: New
C Solution
Staff Salary
Intructors: Abir Das and Sourangshu Bhattacharya
Processing: C++
Solution
Department of Computer Science and Engineering
Indian Institute of Technology, Kharagpur
C and C++
Solutions: A {abir, sourangshu}@[Link]
Comparison
Virtual Function
Pointer Table
Slides taken from NPTEL course on Programming in Modern C++
Module Summary
by Prof. Partha Pratim Das
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 1
Weekly Recap
Module 31
Intructors: Abir
Das and
Sourangshu
• Understood type casting – implicit as well as explicit – for built-in types, unrelated
Bhattacharya types, and classes on a hierarchy
Weekly Recap • Understood the notions of upcast and downcast
Objectives &
Outline • Understood Static and Dynamic Binding for Polymorphic type
Staff Salary
Processing: New
• Understood virtual destructors, Pure Virtual Functions, and Abstract Base Class
C Solution
• Designed the solution for a staff salary processing problem using iterative refinement –
Staff Salary
Processing: C++ starting with a simple C solution and repeatedly refining finally to an easy, efficient, and
Solution
C and C++
extensible C++ solution based on flexible polymorphic hierarchy
Solutions: A
Comparison
Virtual Function
Pointer Table
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 2
Module Objectives
Module 31
Intructors: Abir
Das and
Sourangshu
• Introduce a new C solution with function pointers
Bhattacharya
• Understand Virtual Function Table for dynamic binding (polymorphic dispatch)
Weekly Recap
Objectives &
Outline
Staff Salary
Processing: New
C Solution
Staff Salary
Processing: C++
Solution
C and C++
Solutions: A
Comparison
Virtual Function
Pointer Table
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 3
Module Outline
Module 31
Intructors: Abir
Das and
Sourangshu
Bhattacharya
1 Weekly Recap
Weekly Recap
Objectives & 2 Staff Salary Processing: New C Solution
Outline
Staff Salary
Processing: New
C Solution
3 Staff Salary Processing: C++ Solution
Staff Salary
Processing: C++
Solution
4 C and C++ Solutions: A Comparison
C and C++
Solutions: A
Comparison
Virtual Function
5 Virtual Function Pointer Table
Pointer Table
Module Summary
6 Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 4
Staff Salary Processing: New C Solution
Module 31
Intructors: Abir
Das and
Sourangshu
Bhattacharya
Weekly Recap
Objectives &
Outline
Staff Salary
Processing: New
C Solution
Staff Salary
Processing: C++
Solution
C and C++
Solutions: A
Comparison
Virtual Function
Pointer Table
Staff Salary Processing: New C Solution
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 5
Staff Salary Processing: Problem Statement: RECAP (Module 29)
Module 31
Intructors: Abir
Das and
Sourangshu
• An organization needs to develop a salary processing application for its staff
Bhattacharya
• At present it has an engineering division only where Engineers and Managers work.
Weekly Recap Every Engineer reports to some Manager. Every Manager can also work like an Engineer
Objectives &
Outline • The logic for processing salary for Engineers and Managers are different as they have
Staff Salary different salary heads
Processing: New
C Solution • In future, it may add Directors to the team. Then every Manager will report to some
Staff Salary
Processing: C++ Director. Every Director could also work like a Manager
Solution
C and C++
• The logic for processing salary for Directors will also be distinct
Solutions: A
Comparison • Further, in future it may open other divisions, like Sales division, and expand the
Virtual Function workforce
Pointer Table
Module Summary • Make a suitable extensible design
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 6
C Solution: Function Pointers
Engineer + Manager + Director: RECAP (Module 29)
Module 31
Intructors: Abir
Das and
Sourangshu
• How to represent Engineers, Managers, and Directors?
Bhattacharya
◦ Collection of structs
Weekly Recap • How to initialize objects?
Objectives &
Outline ◦ Initialization functions
Staff Salary
Processing: New
• How to have a collection of mixed objects?
C Solution
◦ Array of union
Staff Salary
Processing: C++
Solution • How to model variations in salary processing algorithms?
C and C++ ◦ struct-specific functions
Solutions: A
Comparison
• How to invoke the correct algorithm for a correct employee type?
Virtual Function
Pointer Table ◦ Function switch
Module Summary ◦ Function pointers
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 7
C Solution: Function Pointers: Engineer + Manager + Director
Module 31 • In Module 29, we have developed a flat C Solution using function switch
Intructors: Abir
Das and
Sourangshu
• In Module 30, we refined the C Solution to develop two types of C++ Solution using
Bhattacharya
◦ Non-polymorphic hierarchy - employing function switch
Weekly Recap ◦ Polymorphic hierarchy - eomploying virtual function
Objectives &
Outline • In Module 29, we had mentioned that in the flat C Solution it is not easy to use function
Staff Salary pointers as the processing functions void ProcessSalaryEngineer(Engineer *), void
Processing: New
C Solution ProcessSalaryManager(Manager *), and void ProcessSalaryDirector(Director *) all
Staff Salary have different types of arguments and therefore a common function pointer type cannot be
Processing: C++
Solution defined
C and C++
Solutions: A
• We can work around this by:
Comparison
◦ Passing the staff object as void *, instead of Engineer *, Manager *, or Director *
Virtual Function
Pointer Table ◦ Cast it to respective object type in the respective function. That is, cast to Engineer * in
Module Summary ProcessSalaryEngineer(Engineer *) and so on
◦ We can then use a function pointer type void (*)(void *)
• We illustrate in the Solution
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 8
C Solution: Function Pointers: Engineer + Manager + Director
#include <stdio.h>
Module 31 #include <string.h>
Intructors: Abir
Das and #include <stdlib.h>
Sourangshu typedef enum E_TYPE { Er, Mgr, Dir } E_TYPE; // Staff tag type
Bhattacharya
typedef void (*psFuncPtr)(void *); // Processing func. ptr. type, passing the object by void *
typedef struct Engineer { char *name_; } Engineer; // Engineer Type
Weekly Recap
Engineer *InitEngineer(const char *name) { Engineer *e = (Engineer *)malloc(sizeof(Engineer));
Objectives & e->name_ = strdup(name); return e;
Outline }
Staff Salary void ProcessSalaryEngineer(void *v) { Engineer *e = (Engineer *)v; // Cast explicitly to the staff object
Processing: New printf("%s: Process Salary for Engineer\n", e->name_);
C Solution
}
Staff Salary typedef struct Manager { char *name_; Engineer *reports_[10]; } Manager; // Manager Type
Processing: C++
Solution
Manager *InitManager(const char *name) { Manager *m = (Manager *)malloc(sizeof(Manager));
m->name_ = strdup(name); return m;
C and C++ }
Solutions: A
Comparison void ProcessSalaryManager(void *v) { Manager *m = (Manager *)v; // Cast explicitly to the staff object
printf("%s: Process Salary for Manager\n", m->name_);
Virtual Function
Pointer Table
}
typedef struct Director { char *name_; Manager *reports_[10]; } Director; // Director Type
Module Summary Director *InitDirector(const char *name) { Director *d = (Director *)malloc(sizeof(Director));
d->name_ = strdup(name); return d;
}
void ProcessSalaryDirector(void *v) { Director *d = (Director *)v; // Cast explicitly to the staff object
printf("%s: Process Salary for Director\n", d->name_);
}
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 9
C Solution: Function Pointers: Engineer + Manager + Director
Module 31 typedef struct Staff {
Intructors: Abir E_TYPE type_; // Staff tag type
Das and
Sourangshu void *p; // Pointer to staff object
Bhattacharya } Staff; // Staff object wrapper
int main() {
Weekly Recap // Array of function pointers
Objectives & psFuncPtr psArray[] = { ProcessSalaryEngineer, ProcessSalaryManager, ProcessSalaryDirector };
Outline
Staff Salary
// Array of staffs
Processing: New Staff staff[] = { { Er, InitEngineer("Rohit") }, { Mgr, InitEngineer("Kamala") },
C Solution { Mgr, InitEngineer("Rajib") }, { Er, InitEngineer("Kavita") },
Staff Salary { Er, InitEngineer("Shambhu") }, { Dir, InitEngineer("Ranjana") } };
Processing: C++
Solution for (int i = 0; i < sizeof(staff) / sizeof(Staff); ++i)
C and C++ psArray[staff[i].type_] // Pick the right processing function for the tag - staff type
Solutions: A (staff[i].p); // Pass the pointer to the object - implicitly cast to void*
Comparison
}
Virtual Function
Pointer Table Rohit: Process Salary for Engineer
Module Summary
Kamala: Process Salary for Manager
Rajib: Process Salary for Manager
Kavita: Process Salary for Engineer
Shambhu: Process Salary for Engineer
Ranjana: Process Salary for Director
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 10
C Solution: Advantages and Disadvantages: RECAP (Module 26)
Annotated for Function Pointers
Module 31
• Advantages
Intructors: Abir
Das and
◦ Solution exists!
Sourangshu ◦ Code is well structured – has patterns
Bhattacharya
• Disadvantages
Weekly Recap
◦ Employee data has scope for better organization
Objectives &
. No encapsulation for data
Outline . Duplication of fields across types of employees – possible to mix up types for them (say, char *
Staff Salary and string)
Processing: New
C Solution
. Employee objects are created and initialized dynamically through Init... functions. How to
release the memory?
Staff Salary
Processing: C++ ◦ Types of objects are managed explicitly by E Type:
Solution . Difficult to extend the design – addition of a new type needs to:
C and C++
Solutions: A
− Add new type code to enum E Type
Comparison − Add a new pointer field in struct Staff for the new type
Virtual Function − Add a new case (if-else or case) based on the new type: Removed using function pointer
Pointer Table . Error prone – developer has to decide to call the right processing function for every type
Module Summary (ProcessSalaryManager for Mgr etc.): Removed using function pointer
◦ Unable to use Function Pointers as each processing function takes a parameter of different type - no
common signature for dispatch
• Recommendation
◦ Use classes for encapsulation on a hierarchy
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 11
Staff Salary Processing: C++ Solution
Module 31
Intructors: Abir
Das and
Sourangshu
Bhattacharya
Weekly Recap
Objectives &
Outline
Staff Salary
Processing: New
C Solution
Staff Salary
Processing: C++
Solution
C and C++
Solutions: A
Comparison
Virtual Function
Pointer Table
Staff Salary Processing: C++ Solution
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 12
C++ Solution: Polymorphic Hierarchy: RECAP
Engineer + Manager + Director: (Module 30)
Module 31
Intructors: Abir
Das and
Sourangshu
Bhattacharya
Weekly Recap
Objectives &
Outline • How to represent Engineers, Managers, and Directors?
Staff Salary
Processing: New
◦ Polymorphic class hierarchy
C Solution
• How to initialize objects?
Staff Salary
Processing: C++
Solution
◦ Constructor / Destructor
C and C++ • How to have a collection of mixed objects?
Solutions: A
Comparison
◦ array of base class pointers
Virtual Function
Pointer Table • How to model variations in salary processing algorithms?
Module Summary
◦ Member functions
• How to invoke the correct algorithm for a correct employee type?
◦ Virtual Functions
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 13
C++ Solution: Polymorphic Hierarchy: RECAP
Engineer + Manager + Director: (Module 30)
Module 31 #include <iostream>
Intructors: Abir #include <string>
Das and
Sourangshu using namespace std;
Bhattacharya
class Engineer {
Weekly Recap protected:
Objectives & string name_;
Outline public:
Staff Salary
Engineer(const string& name) : name_(name) { }
Processing: New virtual ~Engineer() { }
C Solution virtual void ProcessSalary() { cout << name_ << ": Process Salary for Engineer" << endl; }
Staff Salary };
Processing: C++ class Manager : public Engineer {
Solution Engineer *reports_[10];
C and C++ public:
Solutions: A Manager(const string& name) : Engineer(name) { }
Comparison
void ProcessSalary() { cout << name_ << ": Process Salary for Manager" << endl; }
Virtual Function };
Pointer Table class Director : public Manager {
Module Summary Manager *reports_[10];
public:
Director(const string& name) : Manager(name) { }
void ProcessSalary() { cout << name_ << ": Process Salary for Director" << endl; }
};
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 14
C++ Solution: Polymorphic Hierarchy: RECAP
Engineer + Manager + Director: (Module 30)
Module 31
Intructors: Abir
Das and
int main() {
Sourangshu Engineer e1("Rohit"), e2("Kavita"), e3("Shambhu");
Bhattacharya Manager m1("Kamala"), m2("Rajib");
Director d("Ranjana");
Weekly Recap Engineer *staff[] = { &e1, &m1, &m2, &e2, &e3, &d };
Objectives &
Outline for (int i = 0; i < sizeof(staff) / sizeof(Engineer*); ++i)
Staff Salary
staff[i]->ProcessSalary();
Processing: New }
C Solution
Staff Salary
Rohit: Process Salary for Engineer
Processing: C++ Kamala: Process Salary for Manager
Solution Rajib: Process Salary for Manager
C and C++ Kavita: Process Salary for Engineer
Solutions: A Shambhu: Process Salary for Engineer
Comparison Ranjana: Process Salary for Director
Virtual Function
Pointer Table
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 15
C and C++ Solutions: A Comparison
Module 31
Intructors: Abir
Das and
Sourangshu
Bhattacharya
Weekly Recap
Objectives &
Outline
Staff Salary
Processing: New
C Solution
Staff Salary
Processing: C++
Solution
C and C++
Solutions: A
Comparison
Virtual Function
Pointer Table
C and C++ Solutions: A Comparison
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 16
C and C++ Solutions: A Comparison
Module 31
Intructors: Abir C Solution C++ Solution
Das and
Sourangshu
Bhattacharya • How to represent Engineers, Managers, and • How to represent Engineers, Managers, and
Directors? Directors?
Weekly Recap
Objectives & ◦ structs ◦ Polymorphic hierarchy
Outline
• How to initialize objects? • How to initialize objects?
Staff Salary
Processing: New
C Solution
◦ Initialization functions ◦ Ctor / Dtor
Staff Salary • How to have a collection of mixed objects? • How to have a collection of mixed objects?
Processing: C++
Solution ◦ array of union wrappers ◦ array of base class pointers
C and C++
Solutions: A
• How to model variations in salary processing • How to model variations in salary processing
Comparison algorithms? algorithms?
Virtual Function
Pointer Table
◦ functions for structs ◦ class member functions
Module Summary • How to invoke the correct algorithm for a cor- • How to invoke the correct algorithm for a cor-
rect employee type? rect employee type?
◦ Function pointers ◦ Virtual Functions
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 17
C and C++ Solutions: A Comparison
C Solution (Function Pointer) C++ Solution (Virtual Function)
Module 31
Intructors: Abir typedef enum E_TYPE { Er, Mgr, Dir } E_TYPE;
Das and typedef void (*psFuncPtr)(void *);
Sourangshu typedef struct { E_TYPE type_; void *p; } Staff; class Engineer { protected: string name_;
Bhattacharya public: Engineer(const string& name);
typedef struct { char *name_; } Engineer;
Engineer *InitEngineer(const char *name); virtual void ProcessSalary(); };
Weekly Recap
void ProcessSalaryEngineer(void *v); virtual ~Engineer(); };
Objectives & typedef struct { char *name_; } Manager; class Manager : public Engineer {
Outline
Manager *InitManager(const char *name); public: Manager(const string& name);
Staff Salary void ProcessSalaryManager(void *v); void ProcessSalary(); };
Processing: New
typedef struct { char *name_; } Director; class Director : public Manager {
C Solution public: Director(const string& name);
Director *InitDirector(const char *name);
Staff Salary void ProcessSalaryDirector(void *v); void ProcessSalary(); };
Processing: C++
int main() { psFuncPtr psArray[] = { int main() {
Solution
ProcessSalaryEngineer, // Function // Function pointer array is subsumed in
C and C++
ProcessSalaryManager, // pointer // virtual function tables of classes
Solutions: A
Comparison ProcessSalaryDirector }; // array
Staff staff[] = { Engineer e1("Rohit");
Virtual Function Manager m1("Kamala");
Pointer Table { Er, InitEngineer("Rohit") },
{ Mgr, InitEngineer("Kamala") }, Director d("Ranjana");
Module Summary
{ Dir, InitEngineer("Ranjana") } }; Engineer *staff[] = { &e1, &m1, &d };
for (int i = 0; i < for(int i = 0; i <
sizeof(staff)/sizeof(Staff); ++i) sizeof(staff)/sizeof(Engineer*); ++i)
psArray[staff[i].type_](staff[i].p); staff[i]->ProcessSalary();
} }
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 18
Virtual Function Pointer Table
Module 31
Intructors: Abir
Das and
Sourangshu
Bhattacharya
Weekly Recap
Objectives &
Outline
Staff Salary
Processing: New
C Solution
Staff Salary
Processing: C++
Solution
C and C++
Solutions: A
Comparison
Virtual Function
Pointer Table
Virtual Function Pointer Table
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 19
How do virtual functions work?
Module 31
Intructors: Abir
Das and
Sourangshu
• The C Solution with function pointers gives us the lead to implement virtual functions. Here
Bhattacharya
◦ We have used an array of function pointers (psFuncPtr psArray[]) to keep the
Weekly Recap processing functions (void ProcessSalaryEngineer(Engineer *), void
Objectives & ProcessSalaryManager(Manager *), and void ProcessSalaryDirector(Director *))
Outline
indexed by the type tag (enum E TYPE { Er, Mgr, Dir })
Staff Salary
Processing: New ◦ In C++, every class is a separate type - so the tag can be removed if we bind this table
C Solution
(Virtual Function Table or VFT) with the class
Staff Salary
Processing: C++ ◦ Every class can have a VFT with its appropriate processing function pointer put there
Solution
◦ By override, all these functions can have the same signature (void ProcessSalary()) and
C and C++
Solutions: A
can be called through the same expression ((Engineer *)->ProcessSalary())
Comparison
• We now illustrate Virtual Function Table through simple examples to show how does it work
Virtual Function
Pointer Table for inherited, overridden and overloaded member functions
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 20
Virtual Function Pointer Table
Base Class Derived Class
Module 31
Intructors: Abir
Das and class B { class D: public B {
Sourangshu int i; int j;
Bhattacharya
public: public:
B(int i_): i(i_) { } D(int i_, int j_): B(i_), j(j_) { }
Weekly Recap
void f(int); // B::f(B*const, int) void f(int); // D::f(D*const, int)
Objectives & virtual void g(int); // B::g(B*const, int) void g(int); // D::g(D*const, int)
Outline
}; };
Staff Salary
Processing: New
C Solution
B b(100); D d(200, 500);
B *p = &b; B *p = &d;
Staff Salary
Processing: C++ b Object Layout d Object Layout
Solution
C and C++ Object VFT Object VFT
Solutions: A vft → 0 B::g(B*const, int) vft → 0 D::g(D*const, int)
Comparison B::i 100 B::i 200
Virtual Function D::j 500
Pointer Table
Module Summary Source Expression Compiled Expression Source Expression Compiled Expression
b.f(15); B::f(&b, 15); d.f(15); D::f(&d, 15);
p->f(25); B::f(p, 25); p->f(25); B::f(p, 25);
b.g(35); B::g(&b, 35); d.g(35); D::g(&d, 35);
p->g(45); p->vft[0](p, 45); p->g(45); p->vft[0](p, 45);
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 21
Virtual Function Pointer Table
Module 31
Intructors: Abir
Das and
Sourangshu
• Whenever a class defines a virtual function a hidden member variable is added to the
Bhattacharya class which points to an array of pointers to (virtual) functions called the Virtual
Weekly Recap
Function Table (VFT)
Objectives &
Outline
• VFT pointers are used at run-time to invoke the appropriate function implementations,
Staff Salary
because at compile time it may not yet be known if the base function is to be called or
Processing: New
C Solution
a derived one implemented by a class that inherits from the base class
Staff Salary • VFT is class-specific – all instances of the class has the same VFT
Processing: C++
Solution
• VFT carries the Run-Time Type Information (RTTI) of objects
C and C++
Solutions: A
Comparison
Virtual Function
Pointer Table
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 22
Virtual Function Pointer Table
class A { public:
Module 31 virtual void f(int) { } a Object Layout
Intructors: Abir
Das and virtual void g(double) { }
Sourangshu int h(A *) { } Object VFT
Bhattacharya
}; vft → 0 A::f(A*const, int) Defined
class B: public A { public: 1 A::g(A*const, double) Defined
Weekly Recap
void f(int) { }
Objectives & virtual int h(B *) { }
Outline
}; b Object Layout
Staff Salary class C: public B { public:
Processing: New void g(double) { }
C Solution
Object VFT
int h(B *) { } vft → 0 B::f(B*const, int) Overridden
Staff Salary }; 1 A::g(A*const, double) Inherited
Processing: C++
Solution
A a; B b; C c; 2 B::h(B*const, B*) Overloaded
A *pA; B *pB;
C and C++
Solutions: A Source Expression Compiled Expression
Comparison pA->f(2); pA->vft[0](pA, 2); c Object Layout
Virtual Function pA->g(3.2); pA->vft[1](pA, 3.2);
Pointer Table pA->h(&a); A::h(pA, &a); Object VFT
Module Summary
pA->h(&b); A::h(pA, &b); vft → 0 B::f(B*const, int) Inherited
1 C::g(C*const, double) Overridden
pB->f(2); pB->vft[0](pB, 2); 2 C::h(C*const, B*) Overridden
pB->g(3.2); pB->vft[1](pB, 3.2);
pB->h(&a); pB->vft[2](pB, &a);
pB->h(&b); pB->vft[2](pB, &b);
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 23
Module Summary
Module 31
Intructors: Abir
Das and
Sourangshu
• Leveraging an innovative solution to the Salary Processing Application in C using
Bhattacharya function pointers, we compare C and C++ solutions to the problem
Weekly Recap • The new C solution with function pointers is used to explain the mechanism for
Objectives &
Outline
dynamic binding (polymorphic dispatch) based on virtual function tables
Staff Salary
Processing: New
C Solution
Staff Salary
Processing: C++
Solution
C and C++
Solutions: A
Comparison
Virtual Function
Pointer Table
Module Summary
CS20202: Software Engineering Intructors: Abir Das and Sourangshu Bhattacharya 24