From Jason Turner

[class.access.base]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp88iygme_/{from.md → to.md} +52 -31
tmp/tmp88iygme_/{from.md → to.md} RENAMED
@@ -15,25 +15,31 @@ accessible as `private` members of the derived class[^8].
15
  In the absence of an *access-specifier* for a base class, `public` is
16
  assumed when the derived class is defined with the *class-key* `struct`
17
  and `private` is assumed when the class is defined with the *class-key*
18
  `class`.
19
 
 
 
20
  ``` cpp
21
- class B { /* ... */ };
22
- class D1 : private B { /* ... */ };
23
- class D2 : public B { /* ... */ };
24
- class D3 : B { /* ... */ }; // B private by default
25
- struct D4 : public B { /* ... */ };
26
- struct D5 : private B { /* ... */ };
27
- struct D6 : B { /* ... */ }; // B public by default
28
- class D7 : protected B { /* ... */ };
29
- struct D8 : protected B { /* ... */ };
30
  ```
31
 
32
  Here `B` is a public base of `D2`, `D4`, and `D6`, a private base of
33
  `D1`, `D3`, and `D5`, and a protected base of `D7` and `D8`.
34
 
 
 
 
 
35
  A member of a private base class might be inaccessible as an inherited
36
  member name, but accessible directly. Because of the rules on pointer
37
  conversions ([[conv.ptr]]) and explicit casts ([[expr.cast]]), a
38
  conversion from a pointer to a derived class to a pointer to an
39
  inaccessible base class might be ill-formed if an implicit conversion is
@@ -62,10 +68,12 @@ void DD::f() {
62
  ::B* bp2 = (::B*)this; // OK with cast
63
  bp2->mi = 3; // OK: access through a pointer to B.
64
  }
65
  ```
66
 
 
 
67
  A base class `B` of `N` is *accessible* at *R*, if
68
 
69
  - an invented public member of `B` would be a public member of `N`, or
70
  - *R* occurs in a member or friend of class `N`, and an invented public
71
  member of `B` would be a private or protected member of `N`, or
@@ -73,10 +81,12 @@ A base class `B` of `N` is *accessible* at *R*, if
73
  an invented public member of `B` would be a private or protected
74
  member of `P`, or
75
  - there exists a class `S` such that `B` is a base class of `S`
76
  accessible at *R* and `S` is a base class of `N` accessible at *R*.
77
 
 
 
78
  ``` cpp
79
  class B {
80
  public:
81
  int m;
82
  };
@@ -85,58 +95,69 @@ class S: private B {
85
  friend class N;
86
  };
87
 
88
  class N: private S {
89
  void f() {
90
- B* p = this; // OK because class S satisfies the fourth condition
91
- // above: B is a base class of N accessible in f() because
92
- // B is an accessible base class of S and S is an accessible
93
  // base class of N.
94
  }
95
  };
96
  ```
97
 
 
 
98
  If a base class is accessible, one can implicitly convert a pointer to a
99
  derived class to a pointer to that base class ([[conv.ptr]],
100
- [[conv.mem]]). It follows that members and friends of a class `X` can
 
 
101
  implicitly convert an `X*` to a pointer to a private or protected
102
- immediate base class of `X`. The access to a member is affected by the
103
- class in which the member is named. This naming class is the class in
104
- which the member name was looked up and found. This class can be
105
- explicit, e.g., when a *qualified-id* is used, or implicit, e.g., when a
106
- class member access operator ([[expr.ref]]) is used (including cases
107
- where an implicit “`this->`” is added). If both a class member access
108
- operator and a *qualified-id* are used to name the member (as in
109
- `p->T::m`), the class naming the member is the class denoted by the
110
- *nested-name-specifier* of the *qualified-id* (that is, `T`). A member
111
- `m` is accessible at the point *R* when named in class `N` if
 
 
 
 
 
112
 
113
  - `m` as a member of `N` is public, or
114
  - `m` as a member of `N` is private, and *R* occurs in a member or
115
  friend of class `N`, or
116
  - `m` as a member of `N` is protected, and *R* occurs in a member or
117
- friend of class `N`, or in a member or friend of a class `P` derived
118
- from `N`, where `m` as a member of `P` is public, private, or
119
- protected, or
120
  - there exists a base class `B` of `N` that is accessible at *R*, and
121
  `m` is accessible at *R* when named in class `B`.
 
122
  ``` cpp
123
  class B;
124
  class A {
125
  private:
126
  int i;
127
  friend void f(B*);
128
  };
129
  class B : public A { };
130
  void f(B* p) {
131
- p->i = 1; // OK: B* can be implicitly converted to A*,
132
- // and f has access to i in A
133
  }
134
  ```
135
 
136
- If a class member access operator, including an implicit “`this->`,” is
 
 
137
  used to access a non-static data member or non-static member function,
138
  the reference is ill-formed if the left operand (considered as a pointer
139
  in the “`.`” operator case) cannot be implicitly converted to a pointer
140
- to the naming class of the right operand. This requirement is in
141
- addition to the requirement that the member be accessible as named.
 
 
142
 
 
15
  In the absence of an *access-specifier* for a base class, `public` is
16
  assumed when the derived class is defined with the *class-key* `struct`
17
  and `private` is assumed when the class is defined with the *class-key*
18
  `class`.
19
 
20
+ [*Example 1*:
21
+
22
  ``` cpp
23
+ class B { ... };
24
+ class D1 : private B { ... };
25
+ class D2 : public B { ... };
26
+ class D3 : B { ... }; // B private by default
27
+ struct D4 : public B { ... };
28
+ struct D5 : private B { ... };
29
+ struct D6 : B { ... }; // B public by default
30
+ class D7 : protected B { ... };
31
+ struct D8 : protected B { ... };
32
  ```
33
 
34
  Here `B` is a public base of `D2`, `D4`, and `D6`, a private base of
35
  `D1`, `D3`, and `D5`, and a protected base of `D7` and `D8`.
36
 
37
+ — *end example*]
38
+
39
+ [*Note 1*:
40
+
41
  A member of a private base class might be inaccessible as an inherited
42
  member name, but accessible directly. Because of the rules on pointer
43
  conversions ([[conv.ptr]]) and explicit casts ([[expr.cast]]), a
44
  conversion from a pointer to a derived class to a pointer to an
45
  inaccessible base class might be ill-formed if an implicit conversion is
 
68
  ::B* bp2 = (::B*)this; // OK with cast
69
  bp2->mi = 3; // OK: access through a pointer to B.
70
  }
71
  ```
72
 
73
+ — *end note*]
74
+
75
  A base class `B` of `N` is *accessible* at *R*, if
76
 
77
  - an invented public member of `B` would be a public member of `N`, or
78
  - *R* occurs in a member or friend of class `N`, and an invented public
79
  member of `B` would be a private or protected member of `N`, or
 
81
  an invented public member of `B` would be a private or protected
82
  member of `P`, or
83
  - there exists a class `S` such that `B` is a base class of `S`
84
  accessible at *R* and `S` is a base class of `N` accessible at *R*.
85
 
86
+ [*Example 2*:
87
+
88
  ``` cpp
89
  class B {
90
  public:
91
  int m;
92
  };
 
95
  friend class N;
96
  };
97
 
98
  class N: private S {
99
  void f() {
100
+ B* p = this; // OK because class S satisfies the fourth condition above: B is a base class of N
101
+ // accessible in f() because B is an accessible base class of S and S is an accessible
 
102
  // base class of N.
103
  }
104
  };
105
  ```
106
 
107
+ — *end example*]
108
+
109
  If a base class is accessible, one can implicitly convert a pointer to a
110
  derived class to a pointer to that base class ([[conv.ptr]],
111
+ [[conv.mem]]).
112
+
113
+ [*Note 2*: It follows that members and friends of a class `X` can
114
  implicitly convert an `X*` to a pointer to a private or protected
115
+ immediate base class of `X`. *end note*]
116
+
117
+ The access to a member is affected by the class in which the member is
118
+ named. This naming class is the class in which the member name was
119
+ looked up and found.
120
+
121
+ [*Note 3*: This class can be explicit, e.g., when a *qualified-id* is
122
+ used, or implicit, e.g., when a class member access operator (
123
+ [[expr.ref]]) is used (including cases where an implicit “`this->` is
124
+ added). If both a class member access operator and a *qualified-id* are
125
+ used to name the member (as in `p->T::m`), the class naming the member
126
+ is the class denoted by the *nested-name-specifier* of the
127
+ *qualified-id* (that is, `T`). — *end note*]
128
+
129
+ A member `m` is accessible at the point *R* when named in class `N` if
130
 
131
  - `m` as a member of `N` is public, or
132
  - `m` as a member of `N` is private, and *R* occurs in a member or
133
  friend of class `N`, or
134
  - `m` as a member of `N` is protected, and *R* occurs in a member or
135
+ friend of class `N`, or in a member of a class `P` derived from `N`,
136
+ where `m` as a member of `P` is public, private, or protected, or
 
137
  - there exists a base class `B` of `N` that is accessible at *R*, and
138
  `m` is accessible at *R* when named in class `B`.
139
+ \[*Example 3*:
140
  ``` cpp
141
  class B;
142
  class A {
143
  private:
144
  int i;
145
  friend void f(B*);
146
  };
147
  class B : public A { };
148
  void f(B* p) {
149
+ p->i = 1; // OK: B* can be implicitly converted to A*, and f has access to i in A
 
150
  }
151
  ```
152
 
153
+ *end example*]
154
+
155
+ If a class member access operator, including an implicit “`this->`”, is
156
  used to access a non-static data member or non-static member function,
157
  the reference is ill-formed if the left operand (considered as a pointer
158
  in the “`.`” operator case) cannot be implicitly converted to a pointer
159
+ to the naming class of the right operand.
160
+
161
+ [*Note 4*: This requirement is in addition to the requirement that the
162
+ member be accessible as named. — *end note*]
163