Presentation is loading. Please wait.

Presentation is loading. Please wait.

Slide 1 Polymorphism: Part I. Slide 2 Summary: Derived Class * ‘is-a’ relationship n Different from ‘has-a’ or ‘uses-a’, or … by class-in-class * Public.

Similar presentations


Presentation on theme: "Slide 1 Polymorphism: Part I. Slide 2 Summary: Derived Class * ‘is-a’ relationship n Different from ‘has-a’ or ‘uses-a’, or … by class-in-class * Public."— Presentation transcript:

1 Slide 1 Polymorphism: Part I

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

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

4 Slide 4 Polymorphism with inheritance hierarchies * “Program in the general” vs. “program in the specific” * Process objects of classes that are part of the same hierarchy as if they are objects of a single class n E.g., vehicles  4-wheel vehicle  passenger car  sport car n Objects can be created in any part of the chain of hierarchy * 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 COMP1524

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

6 Slide 6 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’

7 Slide 7 Pointers 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 ‘emloyee’, so a base class pointer (employee) can point to a ‘manager’ object * But, a derived class pointer (Manager) CANNOT point to a base class object (employee) as an ‘employee’ is not necessarily a ‘manager’!

8 Slide 8 Good Pointers, but Wrong Functions! void printPay(const Employee& e) { cout << e.pay() << endl; } int main() { Employee e; Manager m; printPay(e); // ok for ‘employee’ printPay(m); // ??? for ‘manager’ ??? } 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()!!!

9 Slide 9 ‘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()!!!

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

11 Slide 11 (non-virtual) Static and (virtual) Dynamic Binding * Non-virtual member functions are resolved statically at compilation time n i.e. the member function is selected based on the type of the pointer (or reference) to the object * Virtual member functions are resolved dynamically at run time n i.e. the member function is selected based on the type of the object! COMP15211

12 Slide 12 Example with more details

13 Slide 13 Invoking functions with pointers/references CommissionEmployee1.h, CommissionEmployee1.cpp, BasePlusCommissionEmployee1.h, BasePlusCommissionEmployee1.cpp, test1a.cpp COMP15213 * Cannot aim derived-class pointer to a base-class object * Aim base-class pointer at base-class object n Invoke base-class functionality * Aim derived-class pointer at derived-class object n Invoke derived-class functionality * Aim base-class pointer at derived-class object n Because derived-class object is an (inherited) object of base class n 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

14 Slide 14  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 COMP15214 class CommissionEmployee { public: CommissionEmployee( const string &, const string &, const string &, double = 0.0, double = 0.0 ); void setFirstName( const string & ); // set first name string getFirstName() const; // return first name... double earnings() const; // calculate earnings void print() const; // print CommissionEmployee object CommissionEmployee1.h

15 Slide 15  Redefine functions earnings and print COMP15215 class BasePlusCommissionEmployee : public CommissionEmployee { public: BasePlusCommissionEmployee( const string &, const string &, const string &, double = 0.0, double = 0.0, double = 0.0 ); void setBaseSalary( double ); // set base salary double getBaseSalary() const; // return base salary double earnings() const; // calculate earnings void print() const; // print BasePlusCommissionEmployee object private: double baseSalary; // base salary }; // end class BasePlusCommissionEmployee BasePlusCommissionEmployee1.h

16 Slide 16 COMP15216 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 Test1a.cpp sample output (1/2)

17 Slide 17 COMP15217 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 Test1a.cpp sample output (2/2)

18 Slide 18 * The pointer must be a base-class pointer, pointing to a derived-class object n 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 derived- class even if the base-class pointer is pointing to the derived-class object * Aim a derived-class pointer at a base-class object is an error n C++ compiler generates error  CommissionEmployee (base-class object) is not a BasePlusCommissionEmployee (derived-class object) n This is because  A derived-class pointer is supposed to be able to access all the derived-class member functions that it points to  If the pointer is pointing to a base class, some of these derived-class functions may not even be available at the base class COMP15218

19 Slide 19 * Cannot assign base-class object to derived-class pointer COMP15219 CommissionEmployee commissionEmployee( "Sue", "Jones", "222-22-2222", 10000,.06 ); BasePlusCommissionEmployee *basePlusCommissionEmployeePtr = 0; // aim derived-class pointer at base-class object // Error: a CommissionEmployee is not a BasePlusCommissionEmployee basePlusCommissionEmployeePtr = &commissionEmployee; Test1b.cpp

20 Slide 20 tester1c: Aiming base-class pointer at derived-class object n 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  Derived-class members cannot be accessed from base-class pointers COMP15220 // aim base-class pointer at derived-class object commissionEmployeePtr = &basePlusCommissionEmployee; // invoke base-class member functions on derived-class // object through base-class pointer (allowed) string firstName = commissionEmployeePtr->getFirstName();

21 Slide 21 CommissionEmployee2.h * Declaring earnings and print as virtual allows them to be overridden n Overridden means superceding the base class codes n Not redefined, meaning that the original function of the base class still exists COMP15221 class CommissionEmployee { public: CommissionEmployee( const string &, const string &, const string &, double = 0.0, double = 0.0 ); void setFirstName( const string & ); // set first name string getFirstName() const; // return first name... virtual double earnings() const; // calculate earnings virtual void print() const; // print CommissionEmployee object

22 Slide 22 BasePlusCommissionEmployee2.h * Functions earnings and print are already virtual – good practice to declare virtual even with overriding function (though optional) COMP15222 class BasePlusCommissionEmployee : public CommissionEmployee { public: BasePlusCommissionEmployee( const string &, const string &, const string &, double = 0.0, double = 0.0, double = 0.0 ); void setBaseSalary( double ); // set base salary double getBaseSalary() const; // return base salary virtual double earnings() const; // calculate earnings virtual void print() const; // print private: double baseSalary; // base salary }; // end class BasePlusCommissionEmployee

23 Slide 23 tester2.cpp (1/3) * Aiming base-class pointer at base-class object and invoking base-class functionality COMP15223 // output objects using static binding cout << "Invoking print function on base-class and derived-class " << "\nobjects with static binding\n\n"; commissionEmployee.print(); // static binding basePlusCommissionEmployee.print(); // static binding // output objects using dynamic binding cout << "\n\n\nInvoking print function on base-class and “ << "derived-class \nobjects with dynamic binding"; // aim base-class pointer at base-class object and print commissionEmployeePtr = &commissionEmployee; cout << "\n\nCalling virtual function print with base-class pointer" << "\nto base-class object invokes base-class " << "print function:\n\n"; commissionEmployeePtr->print(); // invokes base-class print

24 Slide 24 tester2.cpp (2/3) * Aiming derived-class pointer at derived-class object and invoking derived-class functionality COMP15224 // aim derived-class pointer at derived-class object and print basePlusCommissionEmployeePtr = &basePlusCommissionEmployee; cout << "\n\nCalling virtual function print with derived-class “ << "pointer\nto derived-class object invokes derived-class “ << "print function:\n\n"; basePlusCommissionEmployeePtr->print();

25 Slide 25 tester2.cpp (3/3) * Aiming base-class pointer at derived-class object and invoking derived-class functionality via polymorphism and virtual functions COMP15225 // aim base-class pointer at derived-class object and print commissionEmployeePtr = &basePlusCommissionEmployee; cout << "\n\nCalling virtual function print with base-class pointer" << "\nto derived-class object invokes derived- class " << "print function:\n\n"; // polymorphism; invokes BasePlusCommissionEmployee's print; // base-class pointer to derived-class object commissionEmployeePtr->print();

26 Slide 26 tester2.cpp Sample Output (1/3) COMP15226 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

27 Slide 27 tester2.cpp Sample Output (2/3) COMP15227 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

28 Slide 28 tester2.cpp Sample Output (3/3) COMP15228 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

29 Slide 29 Pure Virtual Functions and Abstract Classes

30 Slide 30 Abstract Classes * ‘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. class Employee { string firstName; string familyName; … } class Manager : public Employee { list group; … } class Shape { void rotate(int); void draw(); … } class Circle : public Shape { … } Shape s; ???

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

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

33 Slide 33 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;

34 Slide 34 * 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. class Shape { virtual void rotate(int) = 0; virtual void draw() = 0; … } class Polygon : public Shape { public: bool is_closed() { return true; } } Polygon p; // error!!!

35 Slide 35 Polymorphism: Part II

36 Slide 36 A Test: What is the Output? COMP15236 #include 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;} }; class C: public B { public: C() {} void f() {cout << "C::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; }

37 Slide 37 COMP15237 Output: A::f()

38 Slide 38 Change A* to B* or C*? COMP15238

39 Slide 39 A Test:if we add virtual to class A? COMP15239 class A { public: A() {} virtual void f() {cout << "A::f()" << endl;} };

40 Slide 40 COMP15240 Output: A::f() B::f() C::f()

41 Slide 41 The three corner-stones of OOP * Encapsulation * Inheritance * Polymorphism

42 Slide 42 Encapsulation * Languages such as Pascal and C facilitated development of structured programs * Need for ability to extend and reuse software became evident n This leads to object-oriented programming where objects are built on top of other objects * Data and basic operations for processing the data are encapsulated into a single “entity”. This is made possible with introduction of n Modules n Libraries n Packages * Implementation details are separated from class definition n Client code must use only public operations n Implementation may be changed without affecting client code COMP15242

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

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

45 Slide 45 Pure Virtual Functions and Abstract Classes * We can use the abstract base class to declare pointers and references n 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 * Polymorphism is particularly effective for implementing software systems n Reading or writing data from and to different devices of the same base class * Iterator class n Can traverse all the objects in a container COMP15245

46 Slide 46 COMP152 46 #include using namespace std; class base{ public: virtual void print() = 0; virtual void print2() = 0; }; class derived1: public base{ public: virtual void print(){ cout << "derived1\n"; } virtual void print2(){} // must have this line, // otherwise compiler complains in main() }; class derived2: public base{ public: virtual void print(){ cout << "in derived2\n"; } // do not need to define print2() here as // derived2 is not a concrete class }; class derived3: public derived2{ public: virtual void print2(){ cout << "In derived3\n"; } }; int main(){ derived1 d1; // derived2 d2; compiler complains: // the following virtual functions are abstract: // void base::print2() derived3 d3; d1.print(); d3.print(); // can do that! d3.print2(); return 1; } derived1 in derived2 In derived3

47 Slide 47 dyanmic_cast * We can always cast a (derived) class to one of its base classes * If p is a base class pointer, T* is a derived class pointer n Statically, it is impossible (static_cast fails!) n But dynamically at run-time, we look at the object pointed to by p (if any).  If the object is of class T, then returns a pointer type T* to that object  Otherwise, 0 is returned. COMP15247 dynamic_cast (p); p is a pointer or reference

48 Slide 48 COMP15248 #include using namespace std; class base{ public: virtual void print(){ cout << "Base object\n";} }; class derived: public base{ public: virtual void print(){ cout << "Derived object\n"; } }; int main(){ base* bptr[2]; // check whether it points to a derived obj derived* is_derived; bptr[0] = new base(); bptr[1] = new derived(); // check whether the pointer can be successfully cast is_derived = dynamic_cast (bptr[0]); if(is_derived) cout << "bptr[0] is a derived object.\n"; else cout << "bptr[0] is a base object.\n"; is_derived = dynamic_cast (bptr[1]); if(is_derived) // derived class is_derived -> print(); // call derived functions else // is_derived is NULL; base class bptr[1] -> print(); // call base functions return 0; } bptr[0] is a base object. Derived object

49 Slide 49 Virtual ? Constructors/Destructors COMP15249

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

51 Slide 51 Virtual Destructors * Nonvirtual destructors n Destructors that are not declared with keyword virtual 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 This is because delete may be applied on a base-class object, instead of the derived class * virtual destructors Declared with keyword virtual  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 COMP15251

52 Slide 52 COMP152 52 #include using namespace std; class Base{ public: virtual ~Base() { cout <<"Base Destroyed\n"; } }; class Derived: public Base{ public: virtual ~Derived() { cout << "Derived Destroyed\n"; } }; 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

53 Slide 53 Case Study: Payroll System Using Polymorphism

54 Slide 54 A Payroll System * Enhanced CommissionEmployee-BasePlusCommissionEmployee hierarchy using an abstract base class * Abstract class Employee represents the general concept of an employee n Declares the “interface” to the hierarchy n Each employee has a first name, last name and social security number * Earnings calculated differently and objects printed differently for each derived class COMP15254

55 Slide 55 Creating Abstract Base Class Employee * Provides various get and set functions  Provides functions earnings and print Function earnings depends on type of employee, so declared pure virtual  Not enough information in class Employee for a default implementation Function print is virtual, but not pure virtual  Default implementation provided in Employee * Example maintains a vector of Employee pointers n Polymorphically invokes proper earnings and print functions COMP15255

56 Slide 56 Polymorphic Interface COMP15256

57 Slide 57 Employee.h * 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 COMP15257 // pure virtual function makes Employee abstract base class virtual double earnings() const = 0; // pure virtual virtual void print() const; // virtual private: string firstName; string lastName; string socialSecurityNumber; }; // end class Employee

58 Slide 58 Creating Concrete Derived Class * SalariedEmployee inherits from Employee n Includes a weekly salary  Overridden earnings function incorporates weekly salary  Overridden print function incorporates weekly salary n Is a concrete class (implements all pure virtual functions in abstract base class) COMP15258

59 Slide 59 SalariedEmployee.h  SalariedEmployee 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) COMP15259 class SalariedEmployee : public Employee { public: SalariedEmployee( const string &, const string &, const string &, double = 0.0 ); void setWeeklySalary( double ); // set weekly salary double getWeeklySalary() const; // return weekly salary // keyword virtual signals intent to override virtual double earnings() const; // calculate earnings virtual void print() const; // print SalariedEmployee object private: double weeklySalary; // salary per week };

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

61 Slide 61 Creating Concrete Derived Class * HourlyEmployee inherits from Employee n Includes a wage and hours worked  Overridden earnings function incorporates the employee’s wages multiplied by hours (taking time-and-a-half pay into account)  Overridden print function incorporates wage and hours worked n Is a concrete class (implements all pure virtual functions in abstract base class) COMP15261

62 Slide 62 HourlyEmployee.h COMP15262 class HourlyEmployee : public Employee { public: HourlyEmployee( const string &, const string &, const string &, double = 0.0, double = 0.0 ); void setWage( double ); // set hourly wage double getWage() const; // return hourly wage void setHours( double ); // set hours worked double getHours() const; // return hours worked // keyword virtual signals intent to override virtual double earnings() const; // calculate earnings virtual void print() const; // print HourlyEmployee object private: double wage; // wage per hour double hours; // hours worked for week }; // end class HourlyEmployee

63 Slide 63 Creating Concrete Derived Class * CommissionEmployee inherits from Employee n Includes gross sales and commission rate  Overridden earnings function incorporates gross sales and commission rate  Overridden print function incorporates gross sales and commission rate n Concrete class (implements all pure virtual functions in abstract base class) * ComissionEmployee.h, CommissionEmployee.cpp COMP15263

64 Slide 64 Creating Indirect Concrete Derived Class * BasePlusCommissionEmployee inherits from CommissionEmployee n Includes base salary  Overridden earnings function that incorporates base salary  Overridden print function that incorporates base salary n Concrete class  Not necessary to override earnings to make it concrete, can inherit implementation from CommissionEmployee  Although we do override earnings to incorporate base salary COMP15264

65 Slide 65 BasePlusComissionEmployee.h * BasePlusCommissionEmployee inherits from CommissionEmployee, which is already concrete COMP15265 class BasePlusCommissionEmployee : public CommissionEmployee { public: BasePlusCommissionEmployee( const string &, const string &, const string &, double = 0.0, double = 0.0, double = 0.0 ); void setBaseSalary( double ); // set base salary double getBaseSalary() const; // return base salary // keyword virtual signals intent to override virtual double earnings() const; // calculate earnings virtual void print() const; // print BasePlusCommissionEmployee object private: double baseSalary; // base salary per week }; // end class BasePlusCommissionEmployee

66 Slide 66 BasePlusComissionEmployee.cpp * Overridden earnings and print functions incorporate base salary COMP15266 // calculate earnings; // override pure virtual function earnings in Employee double BasePlusCommissionEmployee::earnings() const { return getBaseSalary() + CommissionEmployee::earnings(); } // end function earnings // print BasePlusCommissionEmployee's information void BasePlusCommissionEmployee::print() const { cout << "base-salaried "; CommissionEmployee::print(); // code reuse cout << "; base salary: " << getBaseSalary(); } // end function print

67 Slide 67 Demonstrating Polymorphic Processing * Create objects of types SalariedEmployee, HourlyEmployee, CommissionEmployee and BasePlusCommissionEmployee n Demonstrate manipulating objects with static binding  Using name handles rather than pointers or references  Compiler can identify each object’s type to determine which print and earnings functions to call n Demonstrate manipulating objects polymorphically  Uses a vector of Employee pointers  Invoke virtual functions using pointers and references COMP15267

68 Slide 68 payroll.cpp (1/3) * vector of Employee pointers, will be used to demonstrate dynamic binding COMP15268 // create vector of four base-class pointers vector employees( 4 ); // initialize vector with Employees employees[ 0 ] = &salariedEmployee; employees[ 1 ] = &hourlyEmployee; employees[ 2 ] = &commissionEmployee; employees[ 3 ] = &basePlusCommissionEmployee; cout << "Employees processed polymorphically via dynamic binding:\n\n";

69 Slide 69 payroll.cpp (2/3) * Demonstrate dynamic binding using pointers, then references COMP15269 // call virtualViaPointer to print each Employee's information // and earnings using dynamic binding cout << "Virtual function calls made off base-class pointers:\n\n"; for ( size_t i = 0; i < employees.size(); i++ ) virtualViaPointer( employees[ i ] ); // call virtualViaReference to print each Employee's // information and earnings using dynamic binding cout << "Virtual function calls made off base-class references:\n\n"; for ( size_t i = 0; i < employees.size(); i++ ) virtualViaReference( *employees[ i ] ); // note dereferencing return 0; } // end main

70 Slide 70 payroll.cpp (3/3) * Using references and pointers cause virtual functions to be invoked polymorphically COMP15270 // call Employee virtual functions print and earnings off a // base-class pointer using dynamic binding void virtualViaPointer( const Employee * const baseClassPtr ) { baseClassPtr->print(); cout earnings() << "\n\n"; } // end function virtualViaPointer // call Employee virtual functions print and earnings off a // base-class reference using dynamic binding void virtualViaReference( const Employee &baseClassRef ) { baseClassRef.print(); cout << "\nearned $" << baseClassRef.earnings() << "\n\n"; } // end function virtualViaReference

71 Slide 71 payroll.cpp Sample Output (1/3) COMP15271 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

72 Slide 72 payroll.cpp Sample Output (2/3) COMP15272 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

73 Slide 73 payroll.cpp Sample Output (3/3) COMP15273 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


Download ppt "Slide 1 Polymorphism: Part I. Slide 2 Summary: Derived Class * ‘is-a’ relationship n Different from ‘has-a’ or ‘uses-a’, or … by class-in-class * Public."

Similar presentations


Ads by Google