160 likes | 252 Views
Object Oriented Programming in C++. Chapter 7 Dynamic Binding. class Employee. class Employee { public: Employee( String nm, int ag ) ; Employee( ) ; void print( void ) const ; private: String name; int age; };. Implementation of Employee’s methods.
E N D
Object Oriented ProgramminginC++ Chapter 7 Dynamic Binding
class Employee class Employee { public: Employee( String nm, int ag ) ; Employee( ) ; void print( void ) const ; private: String name; int age; };
Implementation of Employee’s methods Employee ::Employee( String nm, int ag ) : age( ag ), name( nm ) { } Employee ::Employee( ) : age(0), name("") { } void Employee ::print( void ) const { cout << "Name " << name << " Age " << age; }
Manager inherits from Employee class Manager : public Employee { public: Manager( String nm, int ag, int lev ); Manager( ); void print( void ) const private: int level; }; print redefined
Manager’smember functions Manager ::Manager( char* nm, int ag, int lev ) : Employee( nm, ag ), level( lev ) { } Manager :: Manager( ) : Employee( ), level( 0 ) { } void Manager :: print( void ) const { Employee::print(); cout << " Level " << level; }
Using Employee and Manager Employee emp1( “Shem ", 42 ); Employee emp2( “Ham ", 32 ); Manager mgr1( “Yefet", 50, 3 ); Manager mgr2( “Zefet ", 46, 2 ); emp1.print();// Employee’s print function emp2.print();// “ “ “ mgr1.print();// Manager’s print function mgr2.print();// “ “ “ Name Shem Age 42 Name Ham Age 32 Name Yefet Age 50 Level 3 Name Zefet Age 46 Level 2
Storing pointers to objects, then printing Employee* employees[4]; // array of pointers to Employee objects employees[0] = &emp1; // Store address of emp1 in first array element employees[1] = &mgr1; // store address of mgr1 in second element employees[2] = &emp2; // etc. employees[3] = &mgr2; // etc. for ( int i = 0; i < 4; i++ ) { employees[i]->print(); // call print member function of each element cout << endl; }
Oops… Name Shem Age 42 Name Yefet Age 50 Name Ham Age 32 Name Zefet Age 46 • Not what we had expected • The Employee version of print() has been invoked for objects of both Employee and Manager • This was determined at compile-time - Static Binding by reference to the array element type (Employee*) • We want the Manager version of print()to be called for Manager objects
Solution • Make Employee’sprint method virtual • Ensures that the version of print() invoked is determined at run-time by reference to the actual object referred to by each pointer stored in the array - Dynamic Binding • In Employee class declaration: virtual void print( void ) const { cout << "Name " << name << " Age " << age; } • No change required to class Manager
Output from loop with virtual print() Name Shem Age 42 Name Yefet Age 50 Level 3 Name Ham Age 32 Name Zefet Age 46 Level 2 • OK now. • Base class function is virtual - ensures Dynamic Binding
Virtual functions • Default is static binding - faster • Dynamic binding only if specifically requested
Abstract base classes • classes which we never intend to instantiate • cannot create objects of this class • can declare pointers to this class • vs concrete classes • too generic to define real objects • used only as a base class for inheritance • required to have a derived class • made by defining 1 or more virtual functions (methods) as pure • if derived class does not override all pvf, it becomes an abstract class as well! • A pure virtual function - virtual void print( void ) const = 0; // no parentheses
Employee as an Abstract class class Employee { public: Employee( String nm, int ag ) : age( ag ), name( nm ) { } Employee( ): age(0), name("") { } virtual void print( void ) const = 0; protected: String name; int age; };
Class Manager class Manager : public Employee { public: Manager( String nm, int ag, int lev ) : Employee( nm, ag ), level( lev ) { } Manager( ) : Employee(), level( 0 ){ } // redefinition of pure virtual function void print( void ) const { cout << "Name " << name << " Age " << age << " Level " << level; } private: int level; };
Class Worker class Worker : public Employee { public: Worker ( String nm, int ag ) : Employee( nm, ag ) { } Worker ( ) : Employee() { } // redefinition of pure virtual function void print( void ) const { cout << "Name " << name << " Age " << age; } };
Worker wkr1( “Shem ", 42 ); Worker wkr2( “Ham ", 32 ); Manager mgr1( “Yefet", 50, 3 ); Manager mgr2( “Zefet ", 46, 2 ); Employee* employees[4]; employees[0] = &wkr1; employees[1] = &mgr1; employees[2] = &wkr2; employees[3] = &mgr2; for ( int i = 0; i < 4; i++ ) { employees[i]->print();cout << endl; } Name Shem Age 42 Name Yefet Age 50 Level 3 Name Ham Age 32 Name Zefet Age 46 Level 2 2 derived classes in Employee* array