forked from cirosantilli/cpp-cheat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
virtual.cpp
147 lines (113 loc) · 3.01 KB
/
virtual.cpp
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
# virtual
Keyword that enables polymorphism.
http://stackoverflow.com/questions/2391679/can-someone-explain-c-virtual-methods
*/
#include "common.hpp"
int main() {
/*
# Polymorphism
The pointer t the base class can have different effects
depending on what actual object it points to.
# Override method
Method of the derived class with compatible signature to base class
overrides the base method.
For incompatible signatures, or base methods that are not virtual,
_hiding_ happnes, not overhiding.
*/
{
class Base {
public:
virtual int f() { return 0; }
};
class Derived1 : public Base {
public:
virtual int f() { return 1; }
};
class Derived2 : public Base {
public:
virtual int f() { return 2; }
};
// Depending on what bp points to, we call different functions.
// This is 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!
{
class Base {
public:
int f() { return 0; }
};
class Derived : public Base {
public:
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.
*/
{
class Base {
public:
virtual int f() { return 0; }
};
class Derived : public Base {
public:
virtual int f(int i) { 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.
//assert(bp->f(1) == 1);
}
/*
`virtual` on the overriding method is optional, although highly recommended.
Even if not given, the method is still `virtual`.
So just always use it.
*/
{
class Base {
public:
virtual int f() { return 0; }
};
class Derived1 : public Base {
public:
/* Note no virtual here. */
int f() { return 1; }
};
class Derived2 : public Derived1 {
public:
int f() { return 2; }
};
// Polymorphism works. So Derived::f is actually `virtual`.
Derived1 *dp;
Derived2 d2;
dp = &d2;
assert(dp->f() == 2);
}
}