File: nestedfriends.yo

package info (click to toggle)
c%2B%2B-annotations 8.2.0-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 11,804 kB
  • ctags: 2,845
  • sloc: cpp: 15,418; makefile: 2,473; ansic: 165; perl: 90; sh: 29
file content (204 lines) | stat: -rw-r--r-- 6,976 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
To grant nested classes access rights to the private members of their
surrounding class, to grant access to the private members of other nested
classes, or to grant a surrounding class access to the private members of its
nested classes the hi(friend: nested classes)tt(friend) keyword must be used.

Consider the following situation where a class tt(Surround) has two nested
classes tt(FirstWithin) and tt(SecondWithin). Each of the three classes has a
static data member tt(int s_variable):
        verb(
    class Surround
    {
        static int s_variable;
        public:
            class FirstWithin
            {
                static int s_variable;
                public:
                    int value();
            };
            int value();
        private:
            class SecondWithin
            {
                static int s_variable;
                public:
                    int value();
            };
    };
        )
    If the class tt(Surround) should be able to access tt(FirstWithin) and
tt(SecondWithin)'s private members, these latter two classes must declare
tt(Surround) to be their friend. The function tt(Surround::value) can
thereupon access the private members of its nested classes. For example (note
the tt(friend) declarations in the two nested classes):
        verb(
    class Surround
    {
        static int s_variable;
        public:
            class FirstWithin
            {
                friend class Surround;
                static int s_variable;
                public:
                    int value();
            };
            int value();
        private:
            class SecondWithin
            {
                friend class Surround;
                static int s_variable;
                public:
                    int value();
            };
    };
    inline int Surround::FirstWithin::value()
    {
        FirstWithin::s_variable = SecondWithin::s_variable;
        return (s_variable);
    }
        )
    To allow the nested classes access to the private members of their
surrounding class, the class tt(Surround) must declare its nested classes as
friends. As the tt(friend) keyword may only be used when the class that is to
become a friend is already known as a class by the compiler, either a
i(forward declaration) of the nested classes is required (to be followed by
the friend declaration), or the friend declaration follows the definition of
the nested classes. The forward declaration followed by the friend declaration
looks like this:
        verb(
    class Surround
    {
        public:
            class FirstWithin;
            class SecondWithin;
            friend class FirstWithin;
            friend class SecondWithin;
            class FirstWithin
            { ... };
        ...
    };
        )
    Alternatively, the friend declaration may follow the definition of the
classes. A class can be declared a friend following its definition, with
in-class code already using the fact that it will be declared a friend of the
outer class. Furthermore, in-class defined nested class members may already
use members of the surrounding class that have not yet been seen by the
compiler. Finally note that `tt(s_variable)' which is
  hi(nested class: member access) defined in the class tt(Surround) may be
accessed by the nested classes as tt(Surround::s_variable):
        verb(
    class Surround
    {
        static int s_variable;
        public:
            class FirstWithin
            {
                friend class Surround;
                static int s_variable;
                public:
                    int value();
            };
            friend class FirstWithin;
            int value();

        private:
            class SecondWithin
            {
                friend class Surround;
                static int s_variable;
                public:
                    int value();
            };
            static void classMember();

            friend class SecondWithin;
    };
    inline int Surround::value()
    {
        FirstWithin::s_variable = SecondWithin::s_variable;
        return s_variable;
    }
    inline int Surround::FirstWithin::value()
    {
        Surround::s_variable = 4;
        Surround::classMember();
        return s_variable;
    }
    inline int Surround::SecondWithin::value()
    {
        Surround::s_variable = 40;
        return s_variable;
    }
        )
    Finally, tt(friend) declarations must be applied to grant the nested
classes access to each other's private members. To grant tt(FirstWithin)
access to tt(SecondWithin)'s private members nothing but a tt(friend)
declaration in tt(SecondWithin) is required. However, to grant
tt(SecondWithin) access to tt(FirstWithin)'s private members the class
tt(FirstWithin) cannot simply use tt(friend class SecondWithin), as
tt(SecondWithin)'s definition is as yet unknown. A i(forward declaration) of
tt(SecondWithin) is required and this forward declaration must be provided by
the class tt(Surround), rather than by the class tt(FirstWithin).

    Clearly, a forward declaration like `tt(class SecondWithin)' makes no
sense in the class
tt(FirstWithin) itself, as this would refer to an external
(global) class tt(SecondWithin). Likewise, the
forward declaration of the nested class tt(SecondWithin) cannot be provided
inside
tt(FirstWithin) as tt(class Surround::SecondWithin). Doing so would generate
the following error message:
        quote(`Surround' does not have a nested type named `SecondWithin')

Here the class tt(SecondWithin) must be declared by the class tt(Surround),
before the class tt(FirstWithin) has been defined. This way tt(SecondWithin)'s
friend declaration is accepted inside tt(FirstWithin).

The following example shows the classes having full access to all private
members of all classes:
        verb(
    class Surround
    {
        class SecondWithin;
        static int s_variable;
        public:
            class FirstWithin
            {
                friend class Surround;
                friend class SecondWithin;
                static int s_variable;
                public:
                    int value();
            };
            friend class FirstWithin;
            int value();
        private:
            class SecondWithin
            {
                friend class Surround;
                friend class FirstWithin;
                static int s_variable;
                public:
                    int value();
            };
            friend class SecondWithin;
    };
    inline int Surround::value()
    {
        FirstWithin::s_variable = SecondWithin::s_variable;
        return s_variable;
    }
    inline int Surround::FirstWithin::value()
    {
        Surround::s_variable = SecondWithin::s_variable;
        return s_variable;
    }
    inline int Surround::SecondWithin::value()
    {
        Surround::s_variable = FirstWithin::s_variable;
        return s_variable;
    }
        )