-
-
Notifications
You must be signed in to change notification settings - Fork 617
Expand file tree
/
Copy pathvirtual.cpp
More file actions
116 lines (91 loc) · 2.43 KB
/
virtual.cpp
File metadata and controls
116 lines (91 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// https://cirosantilli.com/linux-kernel-module-cheat#cpp
#include <cassert>
int main() {
// Hello world.
{
struct Base {
virtual int f() { return 0; }
};
struct Derived1 : public Base {
virtual int f() override { return 1; }
};
struct Derived2 : public Base {
// virtual not required on the last derived method.
int f() override { return 2; }
};
// Depending on what bp actually points to, we call different functions.
// This is what is called polymorphism.
Base *bp;
Base b;
bp = &b;
assert(bp->f() == 0);
Derived1 d1;
bp = &d1;
assert(bp->f() == 1);
Derived2 d2;
bp = &d2;
assert(bp->f() == 2);
}
// Without `virtual`, no polymorphism happens!
// We get name hiding instead.
{
struct Base {
int f() { return 0; }
};
struct Derived : public Base {
int f() { return 1; }
};
Base *bp;
Base b;
bp = &b;
assert(bp->f() == 0);
Derived d;
bp = &d;
// Base method called!
assert(bp->f() == 0);
}
// If the derived signature is not compatible with the virtual,
// no polymorphism happens!
//
// Also see "covariant return" for compatibility of return types.
//
// This is why you should always use override to prevent such bugs.
{
struct Base {
virtual int f() { return 0; }
};
class Derived : public Base {
virtual int f(int i) /* override */ { return i; }
};
Base *bp;
Base b;
bp = &b;
assert(bp->f() == 0);
Derived d;
bp = &d;
// Base method called!
assert(bp->f() == 0);
// ERROR: no matching function.
#if 0
assert(bp->f(1) == 1);
#endif
}
// Polymorphic calls cannot be made from constructors.
// https://stackoverflow.com/questions/1453131/how-can-i-get-polymorphic-behavior-in-a-c-constructor
{
struct Base {
int i;
Base() {
i = f();
}
virtual int f() { return 0; }
};
class Derived : public Base {
int f() override { return i; }
};
Base b;
assert(b.i == 0);
Derived d;
assert(d.i == 0);
}
}