// testpvir.cc // show how a virtual function in a base class gets called // demonstrate polymorphism // compare this file to test_vir.cc that does not use 'virtual' class Base // a base class { public: void f(void); virtual void v(void) = 0; // makes v a pure virtual function }; // makes Base an abstract class class D1 : public Base // a derived class { // inherits both f and v public: // then defines both void f(void); virtual void v(void); }; class D2 : public Base // inherits f and v { // defines only v public: virtual void v(void); }; class D3 : public Base { public: void f(void); // no v defined, thus D3 abstract also }; class DD1 : public D1 // a class derived from the a derived class { public: void f(void); virtual void v(void); }; class D4 : public D3 // now make non virtual so we can get instance (object) { public: void v(void); }; int main(void) { Base *bp; // no object but a pointer for each pure virtual class D1 d1, *d1p; D2 d2, *d2p; D3 *d3p; // no object because v() not defined DD1 dd1, *dd1p; D4 d4; // now v() defined and can get object // b.f(); // no longer can get an object for the pure virtual Base class // b.v(); // bp=&b; // can get pointer, but can not use until later class instance // bp->f(); // bp->v(); d1.f(); // D1::f() d1.v(); // D1::v() d1p=&d1; d1p->f(); // D1::f() d1p->v(); // D1::v() no difference with virtual yet bp=&d1; // now, make a pointer to the base type, point to an // object of a derived type of the base type bp->f(); // Base::f() choose function belonging to pointer type bp->v(); // D1::v() now difference with virtual! // run time polymorphism d2.f(); // Base::f() d2.v(); // D2::v() d2p=&d2; d2p->f(); // Base::f() d2p->v(); // D2::v() no difference with virtual yet bp=&d2; // now, make a pointer to the base type, point to an // object of a derived type of the base type bp->f(); // Base::f() choose function belonging to pointer type bp->v(); // D2::v() now difference with virtual! // run time polymorphism // d3.f(); // D3::f() // not with pure virtual // d3.v(); // D3::v() d3p=&d4; d3p->f(); // D3::f() d3p->v(); // D4::v() only choice bp=&d4; // now, make a pointer to the base type, point to an // object of a derived type of the base type bp->f(); // Base::f() choose function belonging to pointer type bp->v(); // D4::v() only choice dd1.f(); // DD1::f() dd1.v(); // DD1::v() dd1p=&dd1; dd1p->f(); // DD1::f() dd1p->v(); // DD1::v() no difference with virtual yet bp=&dd1; // now, make a pointer to the base type, point to an // object of a derived derived type of the base type bp->f(); // Base::f() choose function belonging to pointer type bp->v(); // DD1::v() now difference with virtual! // run time polymorphism return 0; } #include using namespace std; void Base::f(void) // code for all the function prototypes above { // each function just prints its full name cout << "Base::f()" << endl; } void Base::v(void) { cout << "Base::v()" << endl; } void D1::f(void) { cout << "D1::f()" << endl; } void D1::v(void) { cout << "D1::v()" << endl; } void D2::v(void) { cout << "D2::v()" << endl; } void D3::f(void) { cout << "D3::f()" << endl; } void DD1::f(void) { cout << "DD1::f()" << endl; } void DD1::v(void) { cout << "DD1::v()" << endl; } void D4::v(void) { cout << "D4::v()" << endl; } /* results of running above program: D1::f() D1::v() D1::f() D1::v() Base::f() D1::v() Base::f() D2::v() Base::f() D2::v() Base::f() D2::v() D3::f() D4::v() Base::f() D4::v() DD1::f() DD1::v() DD1::f() DD1::v() Base::f() DD1::v() */