File: base.yo

package info (click to toggle)
c%2B%2B-annotations 7.2.0-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 11,484 kB
  • ctags: 2,902
  • sloc: cpp: 15,844; makefile: 2,997; ansic: 165; perl: 90; sh: 29
file content (148 lines) | stat: -rw-r--r-- 6,418 bytes parent folder | download
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
148
    As illustrated in fig(InternalOrganization), an tt(AirAuto) represents
em(two) tt(Vehicle)s. The result is not only an
i(ambiguity) in the functions which access the tt(weight) data, but also the
presence of two tt(weight) fields. This is somewhat redundant, since we can
assume that an tt(AirAuto) has just one weight.

    We can achieve the situation that an tt(AirAuto) is only one tt(Vehicle),
yet used multiple derivation.  This is implemented by defining the i(base class)
that is multiply mentioned in a i(derived class)' inheritance tree as a
    emi(virtual base class).
For the class tt(AirAuto) this means that the derivation of tt(Land) and
tt(Air) is changed:
        verb(
    class Land: virtual public Vehicle
    {
        // etc
    };

    class Auto: public Land
    {
        // etc
    };


    class Air: virtual public Vehicle
    {
        // etc
    };

    class AirAuto: public Auto, public Air
    {
    };
        )
    The i(virtual derivation) ensures that via the tt(Land) route, a
tt(Vehicle) is only added to a class when a virtual base class was not yet
present. The same holds true for the tt(Air) route. This means that we can no
longer say via which route a tt(Vehicle) becomes a part of an tt(AirAuto); we
can only say that there is an embedded tt(Vehicle) object.  The internal
organization of an tt(AirAuto) after virtual derivation is shown in
fig(VirtualBaseClass).
    figure(polymorphism/virtbase)
        (Internal organization of an tt(AirAuto) object when the base
            classes are virtual.)
        (VirtualBaseClass)
    Note the following:
    itemization(
    it() When base classes of a class using multiple derivation are themselves
virtually derived from a base class (as shown above), the
    i(base class constructor) normally called when the derived class
constructor is called, is no longer used: its
    hi(base class initializer: ignored) base class initializer is
em(ignored). Instead, the base class constructor will be called independently
from the derived class constructors. Assume we have two classes, tt(Derived1)
and tt(Derived2), both (possibly virtually) derived from tt(Base). We will
address the hi(multiple inheritance: which constructors) question which
constructors will be called when a class tt(Final: public Derived1, public
Derived2) is defined. To distinguish the several constructors that are
involved, we will use tt(Base1()) to indicate the tt(Base) class constructor
that is called as base class initializer for tt(Derived1) (and analogously:
tt(Base2()) belonging to tt(Derived2)), while tt(Base()) indicates the default
constructor of the class tt(Base). Apart from the tt(Base) class constructor,
we use tt(Derived1()) and tt(Derived2()) to indicate the base class
initializers for the class tt(Final). We now distinguish the following
cases when constructing the class tt(Final: public Derived1, public
Derived2):
        itemization(
        it() classes:
                verb(
                    Derived1: public Base
                    Derived2: public Base
                )
            quote(This is the normal, non virtual multiple derivation. There
                are two tt(Base) classes in the tt(Final) object, and the
                following constructors will be called (in the mentioned
                order):
                verb(
                    Base1(),
                    Derived1(),
                    Base2(),
                    Derived2()
                )
            )
        it() classes:
                verb(
                    Derived1: public Base
                    Derived2: virtual public Base
                )
            quote(Only tt(Derived2) uses virtual derivation. For the
                tt(Derived2) part the base class initializer will be omitted,
                and the default tt(Base) class constructor will be
                called. Furthermore, this `detached' base class constructor
                will be called em(first):
                verb(
                    Base(),
                    Base1(),
                    Derived1(),
                    Derived2()
                )
                Note that tt(Base()) is called first, em(not)
                tt(Base1()). Also note that, as only one derived class uses
                virtual derivation, there are still em(two) tt(Base) class
                objects in the eventual tt(Final) class. Merging of
                hi(base classes: merged) base classes only occurs with
                i(multiple virtual base classes).
            )
        it() classes:
                verb(
                    Derived1: virtual public Base
                    Derived2: public Base
                )
            quote(Only tt(Derived1) uses virtual derivation. For the
                tt(Derived1) part the base class initializer will now be
                omitted, and the default tt(Base) class constructor will be
                called instead. Note the difference with the first case:
                tt(Base1()) is replaced by tt(Base()). Should tt(Derived1)
                happen to use the default tt(Base) constructor, no difference
                would be noted here with the first case:
                verb(
                    Base(),
                    Derived1(),
                    Base2(),
                    Derived2()
                )
            )
        it() classes:
                verb(
                    Derived1: virtual public Base
                    Derived2: virtual public Base
                )
            quote(Here both derived classes use virtual derivation, and so
                only em(one) tt(Base) class object will be present in the
                tt(Final) class. Note that now only one tt(Base) class
                constructor is called: for the detached (merged) tt(Base)
                class object:
                verb(
                    Base(),
                    Derived1(),
                    Derived2()
                )
            )
        )
    it() Virtual derivation is, in contrast to virtual functions, a pure
i(compile-time) issue: whether a derivation is virtual or not defines
how the compiler builds a class definition from other classes.
    )
    Summarizing, using virtual derivation avoids ambiguity when member
functions of a base class are called. Furthermore,
    i(duplication of data members) is avoided.