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