150 likes | 314 Views
Polymorphism. dynamic binding of function name to function call --- polymorphism type of binding function name to function call static binding (compile time) normal function calls dynamic binding (run time) polymorphism of function calls. static binding. #include <iostream>
E N D
Polymorphism • dynamic binding of function name to function call --- polymorphism • type of binding function name to function call • static binding (compile time) • normal function calls • dynamic binding (run time) • polymorphism of function calls
static binding #include <iostream> using namespace std; void sayHi( ); int main( ) { sayHi( ); // static binding, insert entry point at compile time return 0; } void sayHi( ) { cout << “Hello, cruel world!” << endl; }
dynamic binding • virtual function • a function that the decision of function invoking is delayed until run time • if a base class method is declared virtual, then any derived class method with the same signature is automatically virtual • three requirements of polymorphism • an inheritance hierarchy • virtual methods in the hierachy • a pointer or a reference to the base class
class TradesPerson{ public: virtual void sayHi( ) { cout << “Just hi.”<<endl; } }; class Tinker: public TradesPerson{ public: virtual void sayHi( ){ cout <<“Hi, I tinker”<<endl; } }; class Tailor: public TradesPerson{ public: virtual void sayHi( ){ cout <<“Hi, I tailor.”<<endl; } } dynamic binding(example)
int main( ) { TradesPerson* p; int which; cin >> which; switch(which) { case 1: p=new TradesPerson; break; case 2: p=new Tinker; break; case 3: p=new Tailor; break; } p->sayHi( ); delete p; return 0; } note: a pointer to the base class may point to the base class or any of it derived class what happens if not virtual?? dynamic binding (example) 2 Hi, I tinker 3 Hi, I tailor 1 Just hi
int main( ) { TradesPerson* p; Tinker *p1; Tailor *p2; int which; cin >> which; switch(which) { case 1: p=new TradesPerson; p->sayHi( ); break; case 2: p1=new Tinker; p1->sayHi( ); break; case 3: p2=new Tailor; p2 ->sayHi( ); break; } … dynamic binding (example) 2 Hi, I tinker 3 Hi, I tailor 1 Just hi
virtual methods(functions) • virtual destructor • a destructor can be virtual, but a constructor cannot be virtual class C { public: virtual C( ); // ******* Error: constructor virtual C(int); // ******* Error: constructor virtual ~C( ); // ok, destructor virtual void m( ); // ok, regular method };
class A { public: A( ) { cout << endl << “A( ) firing” <<endl; p=new char[5]; } ~A( ) { cout << “~A( ) firing”<<endl; delete[ ] p; } private: char *p; }; class Z: public A { public: Z( ) { cout <<“Z( ) firing” << endl; q = new char[5000]; } virtual destructor
~Z( ) { cout << “~Z( ) firing” <<endl; delete[ ] q; } private: char* q; }; void f( ); int main( ) { for (unsinged i=0; i<3; i++) f( ); return 0; } void f( ){ A* ptr; ptr = new Z; delete ptr; } virtual destructor (cont.)
output: change the base class destructor to virtual function virtual destructor(cont.) A( ) firing Z( ) firing ~A( ) firing A( ) firing Z( ) firing ~A( ) firing A( ) firing Z( ) firing ~A( ) firing A( ) firing Z( ) firing ~Z( ) firing ~A( ) firing A( ) firing Z( ) firing ~Z( ) firing ~A( ) firing A( ) firing Z( ) firing ~Z( ) firing ~A( ) firing
class A { public: A( ) { cout << endl << “A( ) firing” <<endl; p=new char[5]; } virtual ~A( ) { cout << “~A( ) firing”<<endl; delete[ ] p; } private: char *p; }; class Z: public A { public: Z( ) { cout <<“Z( ) firing” << endl; q = new char[5000]; } virtual destructor
virtual ~Z( ) { cout << “~Z( ) firing” <<endl; delete[ ] q; } private: char* q; }; void f( ); int main( ) { for (unsinged i=0; i<3; i++) f( ); return 0; } void f( ){ A* ptr; ptr = new Z; delete ptr; } virtual destructor (cont.)
abstract base classes • abstract base class • a class that no objects can be instantiated • need derived class in order to instantiate objects • must have a pure virtual method • a method whose declaration ends with the special syntax =0, eg.: class ABC { // Abstract Base Class public: virtual void open( ) = 0; // pure virtual method }
class ABC { public: virtual void open ( ) =0; void print ( ) { … } private: … }; class X : public ABC { public: virtual void open ( ) { … } … }; class Y : public ABC{ public: void another( ) { … }; … }; X x1; // ok! not abstract ABC a1; //Error! ABC is abstract Y y1; // Error! Y is abstract -- // open ( ) not overriding abstract base class (example)
share the same interface example: class BasicFile { public: virtual void open( )=0; virtual void close( )=0; virtual void flush( )=0; }; class InFile : public BasicFile { public: virtual void open( ) { …} virtual void close( ) { … } virtual void flush( ) { …} … }; class OutFile : public BasicFile{ public: virtual void open( ) { … } virtual void close( ) { …} virtual void flush( ) { … } … }; abstract base class