Slide 1 Polymorphism Part I Slide 2 Summary

  • Slides: 72
Download presentation
Slide 1 Polymorphism: Part I

Slide 1 Polymorphism: Part I

Slide 2 Summary: Derived Class * ‘is-a’ relationship n Different from ‘has-a’ or ‘uses-a’,

Slide 2 Summary: Derived Class * ‘is-a’ relationship n Different from ‘has-a’ or ‘uses-a’, or … by class-in-class * Public inheritance Public n Private n * ‘protected’ * Constructors/destructors * Redefinition (over-riding) … polymorphism …

Slide 3 Over-riding (not over-loading): Reusing Operations of Base Classes class X { f();

Slide 3 Over-riding (not over-loading): Reusing Operations of Base Classes class X { f(); }; Class Y : public X {}; Derived class may extend or replace base class function of the same name (homonym, homonymous) Therefore, it hides (or overrides) the base-class version of the function n Still possible to call the base class function with scope resolution operator n void Y: : f() { … X: : f(); … } X x; Y y; x. f(); y. f();

Slide 4 class Employee { double pay(); … } int main () { Employee

Slide 4 class Employee { double pay(); … } int main () { Employee e; Manager m; class Manager : public Employee { double pay(); } cout << e. pay(); cout << m. pay(); double Employee: : pay() { return 10000; } double Manager: : pay() { return 10*Employee: : pay(); } }

What is Polymorphism? Slide 5 Polymorphism: poly + morph * (biology): the existence of

What is Polymorphism? Slide 5 Polymorphism: poly + morph * (biology): the existence of two or more forms of individuals within the same animal species * * In programming languages implementation of ‘inheritance’ n Objects belonging to different types (classes) call methods of the same name, but of different behavior. n * ‘over-loading’ is one type of polymorphism: static binding n * Same names, but different arguments ‘over-riding’ is another type, static binding n Same names, but different classes * ‘virtual n function’ is a new type: dynamic binding Same names, but different ‘classes’ with the same hierarchy

Slide 6 Polymorphism with inheritance hierarchies * Treat objects of classes that are part

Slide 6 Polymorphism with inheritance hierarchies * Treat objects of classes that are part of the same hierarchy as if they are objects of a single class E. g. , vehicles 4 -wheel vehicle passenger car sport car n Objects can be created in any part of the chain of hierarchy n * Each object performs the correct tasks for that object’s type n Different actions occur depending on the type of object * New classes can be added with little or no modification to existing code

Slide 7 Practical Motivation the pointers/references are logically ‘compatible’ for the base and derived

Slide 7 Practical Motivation the pointers/references are logically ‘compatible’ for the base and derived classes * with ‘static typing or binding’, at compilation, it can only be fixed based on the ‘type/class’ of the pointers/references, but not the actual objects (base or derived class) * the ‘resolution’ should be delayed to the ‘run-time’, so to introduce ‘dynamic binding’ * ‘virtual function’ explicitly enforces ‘dynamic binding’ *

Slide 8 Pointers, Dynamic Objects, and Classes class Employee { double pay(); … }

Slide 8 Pointers, Dynamic Objects, and Classes class Employee { double pay(); … } class Manager : public Employee { double pay(); } int main() { Employee* ep; ep = new Employee; // OK … ep = new Manager; // OK … Manager* mp; mp = new Manager; // OK … mp = new Employee; // error! } A ‘manager’ is an ‘employee’, so an employee pointer (base class pointer) can point to a manager object (derived class object). But, an ‘employee’ is not necessarily a ‘manager’, so a manager pointer (derived class pointer) CANNOT point to an employee object (base class object)!

Slide 9 Good Pointers, but Wrong Functions! class Employee { double pay(); … }

Slide 9 Good Pointers, but Wrong Functions! class Employee { double pay(); … } class Manager : public Employee { double pay(); } int main() { Employee* ep; ep = new Employee; … ep = new Manager; … ep->pay()? // always Employee: : pay(), // never Manager: : pay()!!! Whose pay?

Slide 10 ‘Virtual’ is polymorphic class Employee { virtual double pay(); … } class

Slide 10 ‘Virtual’ is polymorphic class Employee { virtual double pay(); … } class Manager : public Employee { double pay(); } Employee* ep; ep = new Employee; … ep = new Manager; … ep->pay(); // always the right one, // either Employee: : pay(), or Manager: : pay()!!!

Slide 11 (non-virtual) Static and (virtual) Dynamic Binding * The compiler determines which version

Slide 11 (non-virtual) Static and (virtual) Dynamic Binding * The compiler determines which version of the function or class to use during the compilation time for Function overloading n Function and class template substantiations n * Which n version is called must be deferred to run time This is dynamic binding

Slide 12 ‘Virtual’ is polymorphic class Employee { virtual double pay(); … } class

Slide 12 ‘Virtual’ is polymorphic class Employee { virtual double pay(); … } class Manager : public Employee { double pay(); void meetings(); ? ? ? } Employee* ep; ep = new Employee; … ep = new Manager; … ep->pay(); // always the right one, // either Employee: : pay(), or Manager: : pay()!!!

Slide 13 Example

Slide 13 Example

Invoking functions with pointers/references Slide 14 Commission. Employee 1. h, Commission. Employee 1. cpp,

Invoking functions with pointers/references Slide 14 Commission. Employee 1. h, Commission. Employee 1. cpp, Base. Plus. Commission. Employee 1. h, Base. Plus. Commission. Employee 1. cpp, test 1 a. cpp * * Cannot aim derived-class pointer to a base-class object Aim base-class pointer at base-class object n * Aim derived-class pointer at derived-class object n * Invoke derived-class functionality Aim base-class pointer at derived-class object n n * Invoke base-class functionality Because derived-class object is an (inherited) object of base class Can only invoke base-class functionalities Invoked functionality depends on the pointer/reference type used to invoke the function (which is base or derived object). n Therefore, if it is base pointer, even if it points to a derived-class object, it invokes the functionality of base class

Slide 15 Commission. Employee 1. h class Commission. Employee { public: Commission. Employee( const

Slide 15 Commission. Employee 1. h class Commission. Employee { public: Commission. Employee( const string &, double = 0. 0, double = 0. 0 ); void set. First. Name( const string & ); // set first name string get. First. Name() const; // return first name . . . double earnings() const; // calculate earnings void print() const; // print Commission. Employee object * * Function earnings and print will be redefined in derived classes to calculate the employee’s earnings Function print will be redefined in derived class to print the employee’s information

Slide 16 Base. Plus. Commission. Employee 1. h class Base. Plus. Commission. Employee :

Slide 16 Base. Plus. Commission. Employee 1. h class Base. Plus. Commission. Employee : public Commission. Employee { public: Base. Plus. Commission. Employee( const string &, double = 0. 0, double = 0. 0 ); void set. Base. Salary( double ); // set base salary double get. Base. Salary() const; // return base salary double earnings() const; // calculate earnings void print() const; // print Base. Plus. Commission. Employee object private: double base. Salary; // base salary }; // end class Base. Plus. Commission. Employee * Redefine functions earnings and print

Slide 17 Test 1 a. cpp sample output (1/2) Print base-class and derived-class objects:

Slide 17 Test 1 a. cpp sample output (1/2) Print base-class and derived-class objects: commission employee: Sue Jones social security number: 222 -22 -2222 gross sales: 10000. 00 commission rate: 0. 06 base-salaried commission employee: Bob Lewis social security number: 333 -33 -3333 gross sales: 5000. 00 commission rate: 0. 04 base salary: 300. 00 Calling print with base-class pointer to base-class object invokes base-class print function: commission employee: Sue Jones social security number: 222 -22 -2222 gross sales: 10000. 00 commission rate: 0. 06

Slide 18 Test 1 a. cpp sample output (2/2) Calling print with derived-class pointer

Slide 18 Test 1 a. cpp sample output (2/2) Calling print with derived-class pointer to derived-class object invokes derived-class print function: base-salaried commission employee: Bob Lewis social security number: 333 -33 -3333 gross sales: 5000. 00 commission rate: 0. 04 base salary: 300. 00 Calling print with base-class pointer to derived-class object invokes base-class print function on that derived-class object: commission employee: Bob Lewis social security number: 333 -33 -3333 gross sales: 5000. 00 commission rate: 0. 04

Slide 19 * The pointer must be a base-class pointer, pointing to a derived-class

Slide 19 * The pointer must be a base-class pointer, pointing to a derived-class object All the base class functions of the derived object can be called. This is not a problem because derived class inherits all the functions from the base class. n Because it is a base class pointer, cannot access the members of derivedclass even if the base-class pointer is pointing to the derived-class object n * Aim n a derived-class pointer at a base-class object is an error C++ compiler generates error 1 Commission. Employee (derived-class object) n (base-class object) is not a Base. Plus. Commission. Employee This is because 1 A derived-class pointer is supposed to be able to access all the derived-class member functions that it points to 1 If the pointer is pointing to a base class, some of these derived-class functions may not even be available at the base class

Slide 20 Test 1 b. cpp Commission. Employee commission. Employee( "Sue", "Jones", "222 -22

Slide 20 Test 1 b. cpp Commission. Employee commission. Employee( "Sue", "Jones", "222 -22 -2222", 10000, . 06 ); Base. Plus. Commission. Employee *base. Plus. Commission. Employee. Ptr = 0; // aim derived-class pointer at base-class object // Error: a Commission. Employee is not a Base. Plus. Commission. Employee base. Plus. Commission. Employee. Ptr = &commission. Employee; * Cannot assign base-class object to derived-class pointer

Slide 21 tester 1 c: Aiming base-class pointer at derived-class object Calling functions that

Slide 21 tester 1 c: Aiming base-class pointer at derived-class object Calling functions that exist in base class causes base-class functionality to be invoked n Calling functions that do not exist in base class (may exist in derived class) will result in error n 1 Derived-class members cannot be accessed from base-class pointers // aim base-class pointer at derived-class object commission. Employee. Ptr = &base. Plus. Commission. Employee; // invoke base-class member functions on derived-class // object through base-class pointer (allowed) string first. Name = commission. Employee. Ptr->get. First. Name();

Slide 22 Commission. Employee 2. h class Commission. Employee { public: Commission. Employee( const

Slide 22 Commission. Employee 2. h class Commission. Employee { public: Commission. Employee( const string &, double = 0. 0, double = 0. 0 ); void set. First. Name( const string & ); // set first name string get. First. Name() const; // return first name . . . virtual double earnings() const; // calculate earnings virtual void print() const; // print Commission. Employee object * Declaring earnings and print as virtual allows them to be overridden Overridden means superceding the base class codes n Not redefined, meaning that the original function of the base class still exists n

Slide 23 Base. Plus. Commission. Employee 2. h class Base. Plus. Commission. Employee :

Slide 23 Base. Plus. Commission. Employee 2. h class Base. Plus. Commission. Employee : public Commission. Employee { public: Base. Plus. Commission. Employee( const string &, double = 0. 0, double = 0. 0 ); void set. Base. Salary( double ); // set base salary double get. Base. Salary() const; // return base salary virtual double earnings() const; // calculate earnings virtual void print() const; // print private: double base. Salary; // base salary }; // end class Base. Plus. Commission. Employee * Functions earnings and print are already virtual – good practice to declare virtual even with overriding function (though optional)

Slide 24 tester 2. cpp (1/3) // output objects using static binding cout <<

Slide 24 tester 2. cpp (1/3) // output objects using static binding cout << "Invoking print function on base-class and derived-class " << "nobjects with static bindingnn"; commission. Employee. print(); // static binding base. Plus. Commission. Employee. print(); // static binding // output objects using dynamic binding cout << "nnn. Invoking print function on base-class and “ << "derived-class nobjects with dynamic binding"; // aim base-class pointer at base-class object and print commission. Employee. Ptr = &commission. Employee; cout << "nn. Calling virtual function print with base-class pointer" << "nto base-class object invokes base-class " << "print function: nn"; commission. Employee. Ptr->print(); // invokes base-class print * Aiming base-class pointer at base-class object and invoking base-class functionality

Slide 25 tester 2. cpp (2/3) // aim derived-class pointer at derived-class object and

Slide 25 tester 2. cpp (2/3) // aim derived-class pointer at derived-class object and print base. Plus. Commission. Employee. Ptr = &base. Plus. Commission. Employee; cout << "nn. Calling virtual function print with derived-class “ << "pointernto derived-class object invokes derived-class “ << "print function: nn"; base. Plus. Commission. Employee. Ptr->print(); * Aiming derived-class pointer at derived-class object and invoking derived-class functionality

Slide 26 tester 2. cpp (3/3) // aim base-class pointer at derived-class object and

Slide 26 tester 2. cpp (3/3) // aim base-class pointer at derived-class object and print commission. Employee. Ptr = &base. Plus. Commission. Employee; cout << "nn. Calling virtual function print with base-class pointer" << "nto derived-class object invokes derived class " << "print function: nn"; // polymorphism; invokes Base. Plus. Commission. Employee's print; // base-class pointer to derived-class object commission. Employee. Ptr->print(); * Aiming base-class pointer at derived-class object and invoking derived-class functionality via polymorphism and virtual functions

Slide 27 tester 2. cpp Sample Output (1/3) Invoking print function on base-class and

Slide 27 tester 2. cpp Sample Output (1/3) Invoking print function on base-class and derived-class objects with static binding commission employee: Sue Jones social security number: 222 -22 -2222 gross sales: 10000. 00 commission rate: 0. 06 base-salaried commission employee: Bob Lewis social security number: 333 -33 -3333 gross sales: 5000. 00 commission rate: 0. 04 base salary: 300. 00 Invoking print function on base-class and derived-class objects with dynamic binding

Slide 28 tester 2. cpp Sample Output (2/3) Calling virtual function print with base-class

Slide 28 tester 2. cpp Sample Output (2/3) Calling virtual function print with base-class pointer to base-class object invokes base-class print function: commission employee: Sue Jones social security number: 222 -22 -2222 gross sales: 10000. 00 commission rate: 0. 06 Calling virtual function print with derived-class pointer to derived-class object invokes derived-class print function: base-salaried commission employee: Bob Lewis social security number: 333 -33 -3333 gross sales: 5000. 00 commission rate: 0. 04 base salary: 300. 00

Slide 29 tester 2. cpp Sample Output (3/3) Calling virtual function print with base-class

Slide 29 tester 2. cpp Sample Output (3/3) Calling virtual function print with base-class pointer to derived-class object invokes derived-class print function: base-salaried commission employee: Bob Lewis social security number: 333 -33 -3333 gross sales: 5000. 00 commission rate: 0. 04 base salary: 300. 00

Slide 30 Pure Virtual Functions and Abstract Classes

Slide 30 Pure Virtual Functions and Abstract Classes

Slide 31 Abstract Classes class Employee { string first. Name; string family. Name; …

Slide 31 Abstract Classes class Employee { string first. Name; string family. Name; … } class Shape { void rotate(int); void draw(); … } class Manager : public Employee { list<Employee*> group; … } class Circle : public Shape { … } * * * Shape s; ? ? ? ‘Employee’: both base class and derived class are useful objects ‘Shape’ represents an abstract concept for which objects cannot exist. ‘shape’ makes sense only as the base of some class derived from it.

Slide 32 Virtual Functions class Shape { virtual void rotate(int); virtual void draw(); …

Slide 32 Virtual Functions class Shape { virtual void rotate(int); virtual void draw(); … } class Circle : public Shape { public: void rotate(int); void draw(); … private: int radius; } *A ‘virtual’ function in a base class will be redefined in each derived class

Slide 33 ‘Pure’ Virtual Functions class Shape { virtual void rotate(int) = 0; virtual

Slide 33 ‘Pure’ Virtual Functions class Shape { virtual void rotate(int) = 0; virtual void draw() = 0; … } class Circle : public Shape { public: void rotate(int); void draw(); … private: int radius; } *A ‘virtual’ function is ‘made pure’ by the initializer = 0.

Slide 34 Abstract Class * * * A class with one or more pure

Slide 34 Abstract Class * * * A class with one or more pure virtual functions is an ‘abstract’ class, And no objects of that abstract class can be created! An abstract class is only used as an interface and as a base for other classes. class Shape { virtual void rotate(int) = 0; virtual void draw() = 0; … } class Circle : public Shape { public: void rotate(int); void draw(); … private: int radius; } Shape s; // error!!! Circle c;

Slide 35 * A pure virtual function that is not defined in a derived

Slide 35 * A pure virtual function that is not defined in a derived class remains a pure virtual function, so the derived class is still an abstract class Shape { virtual void rotate(int) = 0; virtual void draw() = 0; … } class Polygon : public Shape { public: bool is_closed() { return true; } } Polygon p; // error!!!

Slide 36 (non-virtual) Static and (virtual) Dynamic Binding * The compiler determines which version

Slide 36 (non-virtual) Static and (virtual) Dynamic Binding * The compiler determines which version of the function or class to use during the compilation time for Function overloading n Function and class template substantiations n * Which n version is called must be deferred to run time This is dynamic binding

Slide 37 ‘Virtual’ is polymorphic class Employee { virtual double pay(); … } class

Slide 37 ‘Virtual’ is polymorphic class Employee { virtual double pay(); … } class Manager : public Employee { double pay(); void meetings(); ? ? ? } Employee* ep; ep = new Employee; … ep = new Manager; … ep->pay(); // always the right one, // either Employee: : pay(), or Manager: : pay()!!!

Slide 38 Abstract Class * * * A class with one or more pure

Slide 38 Abstract Class * * * A class with one or more pure virtual functions is an ‘abstract’ class, And no objects of that abstract class can be created! An abstract class is only used as an interface and as a base for other classes. class Shape { virtual void rotate(int) = 0; virtual void draw() = 0; … } class Circle : public Shape { public: void rotate(int); void draw(); … private: int radius; } Shape s; // error!!! Circle c;

Slide 39 Pure Virtual Functions and Abstract Classes * We can use the abstract

Slide 39 Pure Virtual Functions and Abstract Classes * We can use the abstract base class to declare pointers and references Can point to objects of any concrete class derived from the abstract class n Programs typically use such pointers and references to manipulate derived-class objects polymorphically n * Polymorphism is particularly effective for implementing software systems n Reading or writing data from and to different devices of the same base class * Example: n Iterator class Can traverse all the objects in a container 39

#include <iostream> Slide 40 using namespace std; class base{ public: virtual void print() =

#include <iostream> Slide 40 using namespace std; class base{ public: virtual void print() = 0; virtual void print 2() = 0; }; int main(){ derived 1 d 1; // derived 2 d 2; compiler complains: // the following virtual functions are abstract: // void base: : print 2() derived 3 d 3; d 1. print(); d 3. print(); // can do that! d 3. print 2(); class derived 1: public base{ public: return 1; virtual void print(){ } cout << "derived 1n"; } virtual void print 2(){} // must have this line, // otherwise compiler complains in main() }; class derived 2: public base{ public: virtual void print(){ cout << "in derived 2n"; } // do not need to define print 2() here as // derived 2 is not a concrete class }; derived 1 in derived 2 In derived 3 class derived 3: public derived 2{ public: virtual void print 2(){ cout << "In derived 3n"; } }; 40

Slide 41 Virtual ? Constructors/Destructors 41

Slide 41 Virtual ? Constructors/Destructors 41

Slide 42 * Constructors * Destructors n cannot be virtual can be virtual Usually

Slide 42 * Constructors * Destructors n cannot be virtual can be virtual Usually they should be virtual to have ‘polymorphic’ behavior

Slide 43 * Nonvirtual Virtual Destructors destructors Destructors that are not declared with keyword

Slide 43 * Nonvirtual Virtual Destructors destructors Destructors that are not declared with keyword virtual n If a derived-class object is destroyed explicitly by applying the delete operator to a base-class pointer to the object, the behavior is undefined n This is because delete may be applied on a base-class object, instead of the derived class n * virtual n destructors Declared with keyword virtual 1 That means that all derived-class destructors are virtual With that, if a derived-class object is destroyed explicitly by applying the delete operator to a base-class pointer to the object, the appropriate derived-class destructor is then called n Appropriate base-class destructor(s) will execute afterwards n

Slide 44 #include <iostream> using namespace std; class Base{ public: virtual ~Base() { cout

Slide 44 #include <iostream> using namespace std; class Base{ public: virtual ~Base() { cout <<"Base Destroyedn"; } }; class Derived: public Base{ public: virtual ~Derived() { cout << "Derived Destroyedn"; } }; int main(){ Derived d; Base* bptr = new Derived(); delete bptr; // explicit delete call the destructor immediately bptr = new Derived(); // the object will be deleted by garbage collection // after program exits, and hence no destructor statement return 0; } Derived Destroyed (for “delete bptr”) Base Destroyed Derived Destroyed (for object d going out of scope) Base Destroyed

Slide 45 Polymorphism: Part II

Slide 45 Polymorphism: Part II

Slide 46 What is the Output? #include <iostream> using namespace std; class A {

Slide 46 What is the Output? #include <iostream> using namespace std; class A { public: A() {} void f() {cout << "A: : f()" << endl; } }; class B: public A { public: B() {} void f() {cout << "B: : f()" << endl; } }; int main(){ A* z = new A; z->f(); delete z; A* x = new B; x->f(); delete x; A* y = new C; y->f(); delete y; return 0; } class C: public B { public: C() {} void f() {cout << "C: : f()" << endl; } }; 46

Slide 47 Output: A: : f() 47

Slide 47 Output: A: : f() 47

Slide 48 Change A* to B* or C*? 48

Slide 48 Change A* to B* or C*? 48

Slide 49 If we add ‘virtual’ to class A? class A { public: A()

Slide 49 If we add ‘virtual’ to class A? class A { public: A() {} virtual void f() {cout << "A: : f()" << endl; } }; 49

Slide 50 Output: A: : f() B: : f() C: : f() 50

Slide 50 Output: A: : f() B: : f() C: : f() 50

Slide 51 The three corner-stones of OOP Encapsulation (classes, public, private) * Inheritance (derived)

Slide 51 The three corner-stones of OOP Encapsulation (classes, public, private) * Inheritance (derived) * Polymorphism (virtual) *

Slide 52 Encapsulation (classes, public, private) * Languages such as Pascal and C facilitated

Slide 52 Encapsulation (classes, public, private) * Languages such as Pascal and C facilitated development of structured programs * Data and basic operations for processing the data are encapsulated into a single “entity”. This is made possible with introduction of Modules n Libraries n Packages n * Implementation definition From concrete to abstract data type details are separated from class Client code must use only public operations n Implementation may be changed without affecting client code n 52

Slide 53 Encapsulation with Inheritance basic class features may be re-used in other classes

Slide 53 Encapsulation with Inheritance basic class features may be re-used in other classes * A class can be derived from another class * Some n n New class inherits data and function members from the original class Reusable for the new class * Example: n Consider to add, for example max() and min(), functions to a stack n Could simply add these functions to the class n But … change already proven code * It is better to build “on top” of the proven stack by adding the functions n n The new class is inherited or derived from the stack class Obviously, this concept is different from creating a new class with a stack as its member object 53

Inheritance Features and Advantages Slide 54 * Software n reusability Often used in computer

Inheritance Features and Advantages Slide 54 * Software n reusability Often used in computer game design * Create new class from existing class Seamlessly absorb existing class’s data and behaviors n Enhance with new capabilities n * Derived class inherits from base class More specialized group of objects (e. g. , a character moves, but a soldier and a giant move differently) n Behaviors inherited from base class n 1 Can n customize Additional behaviors 54

Slide 55 Virtual, Dynamic Binding * The compiler determines which version of the function

Slide 55 Virtual, Dynamic Binding * The compiler determines which version of the function or class to use during the compilation time for Function overloading n Function and class template substantiations n * Which n version is called must be deferred to run time This is dynamic binding

Slide 56 Case Study: A Payroll System • Abstract class Employee represents the general

Slide 56 Case Study: A Payroll System • Abstract class Employee represents the general concept of an employee • • Declares the “interface” to the hierarchy Each employee has a first name, last name and social security number Enhanced Commission. Employee-Base. Plus. Commission. Employee hierarchy using an abstract base class Earnings calculated differently and objects printed differently for each derived class

Slide 57 Polymorphic Interface

Slide 57 Polymorphic Interface

Slide 58 Creating abstract class: Employee. h Class Employee { public: … virtual double

Slide 58 Creating abstract class: Employee. h Class Employee { public: … virtual double earnings() const = 0; // pure virtual void print() const; // virtual private: string first. Name; string last. Name; string social. Security. Number; }; * Function earnings is pure virtual, not enough data to provide a default, concrete implementation * Function print is virtual, default implementation provided but derived-classes may override

Slide 59 Creating concrete derived class: Salaried. Employee. h class Salaried. Employee : public

Slide 59 Creating concrete derived class: Salaried. Employee. h class Salaried. Employee : public Employee { public: Salaried. Employee( const string &, double = 0. 0 ); void set. Weekly. Salary( double ); // set weekly salary double get. Weekly. Salary() const; // return weekly salary // keyword virtual signals intent to override virtual double earnings() const; // calculate earnings virtual void print() const; // print Salaried. Employee object private: double weekly. Salary; // salary per week }; * * Salaried. Employee inherits from Employee, must override earnings to be concrete Functions earnings and print in the base class will be overridden (earnings defined for the first time)

Slide 60 Salaried. Employee. cpp // calculate earnings; // override pure virtual function earnings

Slide 60 Salaried. Employee. cpp // calculate earnings; // override pure virtual function earnings in Employee double Salaried. Employee: : earnings() const { return get. Weekly. Salary(); } // end function earnings // print Salaried. Employee's information void Salaried. Employee: : print() const { cout << "salaried employee: "; Employee: : print(); // reuse abstract base-class print function cout << "nweekly salary: " << get. Weekly. Salary(); } // end function print

Slide 61 Creating concrete derived class: Hourly. Employee. h class Hourly. Employee : public

Slide 61 Creating concrete derived class: Hourly. Employee. h class Hourly. Employee : public Employee { public: Hourly. Employee( const string &, double = 0. 0 ); void set. Wage( double ); // set hourly wage double get. Wage() const; // return hourly wage void set. Hours( double ); // set hours worked double get. Hours() const; // return hours worked // keyword virtual signals intent to override virtual double earnings() const; // calculate earnings virtual void print() const; // print Hourly. Employee object private: double wage; // wage per hour double hours; // hours worked for week }; // end class Hourly. Employee * Hourly. Employee inherits from Employee n Includes a wage and hours worked 1 Overridden earnings function incorporates the employee’s wages multiplied by hours (taking time-and-a- half pay into account) 1 Overridden print function incorporates wage and hours worked n Is a concrete class (implements all pure virtual functions in abstract base class) 61

Slide 62 Creating Concrete Derived Class class Commission. Employee : public Employee { public:

Slide 62 Creating Concrete Derived Class class Commission. Employee : public Employee { public: Commission. Employee( const string &, double = 0. 0 ); void set. Commission. Rate( double ); // set commission rate double get. Commission. Rate() const; // return commission rate void set. Gross. Sales( double ); // set gross sales amount double get. Gross. Sales() const; // return gross sales amount // keyword virtual signals intent to override virtual double earnings() const; // calculate earnings virtual void print() const; // print Commission. Employee object private: double gross. Sales; // gross weekly sales double commission. Rate; // commission percentage }; * Commission. Employee inherits from Employee n Includes gross sales and commission rate 1 Overridden earnings function incorporates gross sales and commission rate 1 Overridden print function incorporates gross sales and commission rate n * Concrete class (implements all pure virtual functions in abstract base class) Comission. Employee. h, Commission. Employee. cpp

Slide 63 Creating indirect concrete derived class: Base. Plus. Comission. Employee. h class Base.

Slide 63 Creating indirect concrete derived class: Base. Plus. Comission. Employee. h class Base. Plus. Commission. Employee : public Commission. Employee { public: Base. Plus. Commission. Employee( const string &, double = 0. 0, double = 0. 0 ); void set. Base. Salary( double ); // set base salary double get. Base. Salary() const; // return base salary // keyword virtual signals intent to override virtual double earnings() const; // calculate earnings virtual void print() const; // print Base. Plus. Commission. Employee object private: double base. Salary; // base salary per week }; // end class Base. Plus. Commission. Employee * Base. Plus. Commission. Employee inherits from Commission. Employee n Includes base salary 1 Overridden earnings function that incorporates base salary 1 Overridden print function that incorporates base salary n Concrete class 1 Not necessary to override earnings to make it concrete, can inherit implementation from Commission. Employee 1 Although we do override earnings to incorporate base salary

Slide 64 Base. Plus. Comission. Employee. cpp // calculate earnings; // override pure virtual

Slide 64 Base. Plus. Comission. Employee. cpp // calculate earnings; // override pure virtual function earnings in Employee double Base. Plus. Commission. Employee: : earnings() const { return get. Base. Salary() + Commission. Employee: : earnings(); } // end function earnings // print Base. Plus. Commission. Employee's information void Base. Plus. Commission. Employee: : print() const { cout << "base-salaried "; Commission. Employee: : print(); // code reuse cout << "; base salary: " << get. Base. Salary(); } // end function print * Overridden salary earnings and print functions incorporate base

Demonstrating Polymorphic Processing Slide 65 * Create objects of types Salaried. Employee, Hourly. Employee,

Demonstrating Polymorphic Processing Slide 65 * Create objects of types Salaried. Employee, Hourly. Employee, Commission. Employee and Base. Plus. Commission. Employee n Demonstrate manipulating objects with static binding 1 Using name handles rather than pointers or references 1 Compiler can identify each object’s type to determine which print and earnings functions to call n Demonstrate manipulating objects polymorphically 1 Uses a vector of Employee pointers 1 Invoke virtual functions using pointers and references

Slide 66 payroll. cpp (1/3) // create vector of four base-class pointers vector <

Slide 66 payroll. cpp (1/3) // create vector of four base-class pointers vector < Employee * > employees( 4 ); // initialize vector with Employees employees[ 0 ] = &salaried. Employee; employees[ 1 ] = &hourly. Employee; employees[ 2 ] = &commission. Employee; employees[ 3 ] = &base. Plus. Commission. Employee; cout << "Employees processed polymorphically via dynamic binding: nn"; * vector of Employee pointers, will be used to demonstrate dynamic binding

Slide 67 payroll. cpp (2/3) cout << "Virtual function calls made off base-class pointers:

Slide 67 payroll. cpp (2/3) cout << "Virtual function calls made off base-class pointers: nn"; for ( size_t i = 0; i < employees. size(); i++ ) employees[i]->print(); cout << "nearned $" << employees[i]->earnings() << "nn"; // virtual. Via. Pointer( employees[ i ] ); cout << "Virtual function calls made off base-class references: nn"; for ( size_t i = 0; i < employees. size(); i++ ) (*employees[i]). print(); cout << "nearned $" << (*employees[i]). earnings() << "nn"; // virtual. Via. Reference( *employees[ i ] ); // note dereferencing * Demonstrate references dynamic binding using pointers, then

Slide 68 payroll. cpp (3/3) // call Employee virtual functions print and earnings off

Slide 68 payroll. cpp (3/3) // call Employee virtual functions print and earnings off a // base-class pointer using dynamic binding void virtual. Via. Pointer( const Employee * const base. Class. Ptr ) { base. Class. Ptr->print(); cout << "nearned $" << base. Class. Ptr->earnings() << "nn"; } // end function virtual. Via. Pointer // call Employee virtual functions print and earnings off a // base-class reference using dynamic binding void virtual. Via. Reference( const Employee &base. Class. Ref ) { base. Class. Ref. print(); cout << "nearned $" << base. Class. Ref. earnings() << "nn"; } // end function virtual. Via. Reference * Using references and pointers cause virtual functions to be invoked polymorphically

Slide 69 payroll. cpp Sample Output (1/3) Employees processed individually using static binding: salaried

Slide 69 payroll. cpp Sample Output (1/3) Employees processed individually using static binding: salaried employee: John Smith social security number: 111 -11 -1111 weekly salary: 800. 00 earned $800. 00 hourly employee: Karen Price social security number: 222 -22 -2222 hourly wage: 16. 75; hours worked: 40. 00 earned $670. 00 commission employee: Sue Jones social security number: 333 -33 -3333 gross sales: 10000. 00; commission rate: 0. 06 earned $600. 00 base-salaried commission employee: Bob Lewis social security number: 444 -44 -4444 gross sales: 5000. 00; commission rate: 0. 04; base salary: 300. 00 earned $500. 00

Slide 70 payroll. cpp Sample Output (2/3) Employees processed polymorphically using dynamic binding: Virtual

Slide 70 payroll. cpp Sample Output (2/3) Employees processed polymorphically using dynamic binding: Virtual function calls made off base-class pointers: salaried employee: John Smith social security number: 111 -11 -1111 weekly salary: 800. 00 earned $800. 00 hourly employee: Karen Price social security number: 222 -22 -2222 hourly wage: 16. 75; hours worked: 40. 00 earned $670. 00 commission employee: Sue Jones social security number: 333 -33 -3333 gross sales: 10000. 00; commission rate: 0. 06 earned $600. 00 base-salaried commission employee: Bob Lewis social security number: 444 -44 -4444 gross sales: 5000. 00; commission rate: 0. 04; base salary: 300. 00 earned $500. 00

Slide 71 payroll. cpp Sample Output (3/3) Virtual function calls made off base-class references:

Slide 71 payroll. cpp Sample Output (3/3) Virtual function calls made off base-class references: salaried employee: John Smith social security number: 111 -11 -1111 weekly salary: 800. 00 earned $800. 00 hourly employee: Karen Price social security number: 222 -22 -2222 hourly wage: 16. 75; hours worked: 40. 00 earned $670. 00 commission employee: Sue Jones social security number: 333 -33 -3333 gross sales: 10000. 00; commission rate: 0. 06 earned $600. 00 base-salaried commission employee: Bob Lewis social security number: 444 -44 -4444 gross sales: 5000. 00; commission rate: 0. 04; base salary: 300. 00 earned $500. 00

Slide 72 Here is what we want … i = 0 while (not end)

Slide 72 Here is what we want … i = 0 while (not end) { if *employee[i] is A, print-A, else if B, print-B, else if C, print-C, … i++; } Employee* employee[1000]; i = 0 while (not end) { *employee[i]. print; i++; }