00 /* 01 * virtual.cpp 02 * 03 * Author: Kurt Nørmark / Simonas Saltenis 04 * 05 * Illustrates run-time polymorphism in C++: virtual member functions 06 */ 07 08 // Class B inherits from A. We activate virtual (vf) and non-virtual (f) functions 09 // on a parameter passed by value, by a pointer, and by reference. 10 11 #include <iostream> 12 13 using namespace std; 14 15 class A 16 { 17 double a; 18 public: 19 virtual void vf(double d) 20 { cout << "virtual vf in A" << endl; }; 21 22 void f(double d) 23 { cout << "f in A" << endl; }; 24 }; 25 26 class B : public A 27 { 28 double b; 29 public: 30 void vf(double d) override 31 { cout << "virtual vf in B" << endl; } 32 33 void f(double d) 34 { cout << "f in B" << endl; } 35 }; 36 37 void f1(A a) 38 { 39 a.vf(1.0); // vf in A. Why? Because a is sliced during parameter passing. 40 a.f(2.0); // f in A - static binding. 41 cout << endl; 42 } 43 44 void f2(A *ap) 45 { 46 ap->vf(3.0); // vf in B. 47 ap->A::vf(3.0); // vf in A - enforce call of vf from A, with use of the scope resolution operator :: 48 ap->f(4.0); // f in A - static binding. 49 50 ap->B::f(4.0); // error: 'B' is not a base of 'A' 51 dynamic_cast<B*>(ap)->f(4.0); // f in B - the programmer guarantee that ap is of type B*. 52 53 cout << endl; 54 } 55 56 void f3(A &ar) 57 { 58 ar.vf(5.0); // vf in B 59 ar.A::vf(3.0); // vf in A 60 ar.f(6.0); // f in A 61 // Same as for pointers: 62 ar.B::f(4.0); // error: 'B' is not a base of 'A' 63 dynamic_cast<B&>(ar).f(4.0); // f in B. 64 65 cout << endl; 66 } 67 68 int main() 69 { 70 B b1; 71 // We pass b1 to f1, f2 and f3 72 f1(b1); // ... by value (a copy of b1 is passed) 73 f2(&b1); // ... a pointer by value (a pointer to b1 is passed) 74 f3(b1); // ... by C++ reference (b1 as such is passed) 75 } 76 77