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)  … polymorphism …

3 Slide 3 Over-riding (not over-loading): Reusing Operations of Base Classes Derived class may extend or replace base class function of the same name (homonym, homonymous) n 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 class X { f(); }; Class Y : public X {}; void Y::f() { … X::f(); … } X x; Y y; x.f(); y.f();

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

5 Slide 5 What is Polymorphism? * Polymorphism: poly + morph * (biology): the existence of two or more forms of individuals within the same animal species * In programming languages n implementation of ‘inheritance’ n 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’ is another type, static binding n Same names, but different classes * ‘virtual function’ is a new type: dynamic binding n Same names, but different ‘classes’ with the same hierarchy

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

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

8 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)!

9 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?

10 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()!!!

11 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 n Function overloading n Function and class template substantiations * Which version is called must be deferred to run time n This is dynamic binding

12 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()!!!

13 Slide 13 Example

14 Slide 14 Invoking functions with pointers/references CommissionEmployee1.h, CommissionEmployee1.cpp, BasePlusCommissionEmployee1.h, BasePlusCommissionEmployee1.cpp, test1a.cpp * 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

15 Slide 15  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 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

16 Slide 16  Redefine functions earnings and print 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

17 Slide 17 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)

18 Slide 18 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)

19 Slide 19 * 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

20 Slide 20 * Cannot assign base-class object to derived-class pointer 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

21 Slide 21 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 // 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();

22 Slide 22 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 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

23 Slide 23 BasePlusCommissionEmployee2.h * Functions earnings and print are already virtual – good practice to declare virtual even with overriding function (though optional) 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

24 Slide 24 tester2.cpp (1/3) * Aiming base-class pointer at base-class object and invoking base-class functionality // 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

25 Slide 25 tester2.cpp (2/3) * Aiming derived-class pointer at derived-class object and invoking derived-class functionality // 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();

26 Slide 26 tester2.cpp (3/3) * Aiming base-class pointer at derived-class object and invoking derived-class functionality via polymorphism and virtual functions // 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();

27 Slide 27 tester2.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

28 Slide 28 tester2.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

29 Slide 29 tester2.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

30 Slide 30 Pure Virtual Functions and Abstract Classes

31 Slide 31 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; ???

32 Slide 32 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; }

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

34 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;

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

36 Slide 36 Polymorphism: Part I

37 Slide 37 (non-virtual) Static and (virtual) 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

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

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

40 Slide 40 Polymorphism: Part II

41 Slide 41 What is the Output? 41 #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; }

42 Slide 42 42 Output: A::f()

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

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

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

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

47 Slide 47 Encapsulation (public, private) 47 * 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 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 From concrete to abstract data type

48 Slide 48 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 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 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 48

49 Slide 49 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 49

50 Slide 50 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 * Example: Iterator class n Can traverse all the objects in a container 50

51 Slide 51 51 #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

52 Slide 52 Virtual ? Constructors/Destructors 52

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

54 Slide 54 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

55 Slide 55 #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

56 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 CommissionEmployee-BasePlusCommissionEmployee hierarchy using an abstract base class Earnings calculated differently and objects printed differently for each derived class

57 Slide 57 Polymorphic Interface

58 Slide 58 Creating abstract class: 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 Class Employee { public: … virtual double earnings() const = 0; // pure virtual virtual void print() const; // virtual private: string firstName; string lastName; string socialSecurityNumber; };

59 Slide 59 Creating concrete derived class: 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) 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 // 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.h 61 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 * 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)

62 Slide 62 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 class CommissionEmployee : public Employee { public: CommissionEmployee( const string &, const string &, const string &, double = 0.0, double = 0.0 ); void setCommissionRate( double ); // set commission rate double getCommissionRate() const; // return commission rate void setGrossSales( double ); // set gross sales amount double getGrossSales() const; // return gross sales amount // keyword virtual signals intent to override virtual double earnings() const; // calculate earnings virtual void print() const; // print CommissionEmployee object private: double grossSales; // gross weekly sales double commissionRate; // commission percentage };

63 Slide 63 Creating indirect concrete derived class: BasePlusComissionEmployee.h 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 * 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

64 Slide 64 BasePlusComissionEmployee.cpp * Overridden earnings and print functions incorporate base salary // 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

65 Slide 65 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

66 Slide 66 payroll.cpp (1/3) * vector of Employee pointers, will be used to demonstrate dynamic binding // 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";

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

68 Slide 68 payroll.cpp (3/3) * Using references and pointers cause virtual functions to be invoked polymorphically // 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

69 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

70 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

71 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

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


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