- tmp/tmp4py43fyt/{from.md → to.md} +197 -75
tmp/tmp4py43fyt/{from.md → to.md}
RENAMED
|
@@ -16,29 +16,40 @@ that the member function itself may access.[^7]
|
|
| 16 |
|
| 17 |
Members of a class defined with the keyword `class` are `private` by
|
| 18 |
default. Members of a class defined with the keywords `struct` or
|
| 19 |
`union` are `public` by default.
|
| 20 |
|
|
|
|
|
|
|
| 21 |
``` cpp
|
| 22 |
class X {
|
| 23 |
int a; // X::a is private by default
|
| 24 |
};
|
| 25 |
|
| 26 |
struct S {
|
| 27 |
int a; // S::a is public by default
|
| 28 |
};
|
| 29 |
```
|
| 30 |
|
|
|
|
|
|
|
| 31 |
Access control is applied uniformly to all names, whether the names are
|
| 32 |
-
referred to from declarations or expressions.
|
| 33 |
-
|
| 34 |
-
*
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
``` cpp
|
| 42 |
class A {
|
| 43 |
class B { };
|
| 44 |
public:
|
|
@@ -49,10 +60,12 @@ void f() {
|
|
| 49 |
A::BB x; // OK, typedef name A::BB is public
|
| 50 |
A::B y; // access error, A::B is private
|
| 51 |
}
|
| 52 |
```
|
| 53 |
|
|
|
|
|
|
|
| 54 |
It should be noted that it is *access* to members and base classes that
|
| 55 |
is controlled, not their *visibility*. Names of members are still
|
| 56 |
visible, and implicit conversions to base classes are still considered,
|
| 57 |
when those members and base classes are inaccessible. The interpretation
|
| 58 |
of a given construct is established without regard to access control. If
|
|
@@ -61,13 +74,16 @@ base classes, the construct is ill-formed.
|
|
| 61 |
|
| 62 |
All access controls in Clause [[class.access]] affect the ability to
|
| 63 |
access a class member name from the declaration of a particular entity,
|
| 64 |
including parts of the declaration preceding the name of the entity
|
| 65 |
being declared and, if the entity is a class, the definitions of members
|
| 66 |
-
of the class appearing outside the class’s *member-specification*.
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
| 69 |
|
| 70 |
``` cpp
|
| 71 |
class A {
|
| 72 |
typedef int I; // private member
|
| 73 |
I f();
|
|
@@ -96,20 +112,24 @@ Here, all the uses of `A::I` are well-formed because `A::f`, `A::x`, and
|
|
| 96 |
is as the return type of a member of class `A`. Similarly, the use of
|
| 97 |
`A::B` as a *base-specifier* is well-formed because `D` is derived from
|
| 98 |
`A`, so checking of *base-specifier*s must be deferred until the entire
|
| 99 |
*base-specifier-list* has been seen.
|
| 100 |
|
|
|
|
|
|
|
| 101 |
The names in a default argument ([[dcl.fct.default]]) are bound at the
|
| 102 |
point of declaration, and access is checked at that point rather than at
|
| 103 |
any points of use of the default argument. Access checking for default
|
| 104 |
arguments in function templates and in member functions of class
|
| 105 |
templates is performed as described in [[temp.inst]].
|
| 106 |
|
| 107 |
The names in a default *template-argument* ([[temp.param]]) have their
|
| 108 |
access checked in the context in which they appear rather than at any
|
| 109 |
points of use of the default *template-argument*.
|
| 110 |
|
|
|
|
|
|
|
| 111 |
``` cpp
|
| 112 |
class B { };
|
| 113 |
template <class T> class C {
|
| 114 |
protected:
|
| 115 |
typedef T TT;
|
|
@@ -119,31 +139,39 @@ template <class U, class V = typename U::TT>
|
|
| 119 |
class D : public U { };
|
| 120 |
|
| 121 |
D <C<B> >* d; // access error, C::TT is protected
|
| 122 |
```
|
| 123 |
|
|
|
|
|
|
|
| 124 |
## Access specifiers <a id="class.access.spec">[[class.access.spec]]</a>
|
| 125 |
|
| 126 |
Member declarations can be labeled by an *access-specifier* (Clause
|
| 127 |
[[class.derived]]):
|
| 128 |
|
| 129 |
An *access-specifier* specifies the access rules for members following
|
| 130 |
it until the end of the class or until another *access-specifier* is
|
| 131 |
encountered.
|
| 132 |
|
|
|
|
|
|
|
| 133 |
``` cpp
|
| 134 |
class X {
|
| 135 |
int a; // X::a is private by default: class used
|
| 136 |
public:
|
| 137 |
int b; // X::b is public
|
| 138 |
int c; // X::c is public
|
| 139 |
};
|
| 140 |
```
|
| 141 |
|
|
|
|
|
|
|
| 142 |
Any number of access specifiers is allowed and no particular order is
|
| 143 |
required.
|
| 144 |
|
|
|
|
|
|
|
| 145 |
``` cpp
|
| 146 |
struct S {
|
| 147 |
int a; // S::a is public by default: struct used
|
| 148 |
protected:
|
| 149 |
int b; // S::b is protected
|
|
@@ -152,42 +180,52 @@ private:
|
|
| 152 |
public:
|
| 153 |
int d; // S::d is public
|
| 154 |
};
|
| 155 |
```
|
| 156 |
|
| 157 |
-
|
| 158 |
-
|
|
|
|
|
|
|
| 159 |
|
| 160 |
When a member is redeclared within its class definition, the access
|
| 161 |
specified at its redeclaration shall be the same as at its initial
|
| 162 |
declaration.
|
| 163 |
|
|
|
|
|
|
|
| 164 |
``` cpp
|
| 165 |
struct S {
|
| 166 |
class A;
|
| 167 |
enum E : int;
|
| 168 |
private:
|
| 169 |
class A { }; // error: cannot change access
|
| 170 |
enum E: int { e0 }; // error: cannot change access
|
| 171 |
};
|
| 172 |
```
|
| 173 |
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
declared.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
|
| 180 |
``` cpp
|
| 181 |
class A { };
|
| 182 |
class B : private A { };
|
| 183 |
class C : public B {
|
| 184 |
A* p; // error: injected-class-name A is inaccessible
|
| 185 |
::A* q; // OK
|
| 186 |
};
|
| 187 |
```
|
| 188 |
|
|
|
|
|
|
|
| 189 |
## Accessibility of base classes and base class members <a id="class.access.base">[[class.access.base]]</a>
|
| 190 |
|
| 191 |
If a class is declared to be a base class (Clause [[class.derived]])
|
| 192 |
for another class using the `public` access specifier, the `public`
|
| 193 |
members of the base class are accessible as `public` members of the
|
|
@@ -203,25 +241,31 @@ accessible as `private` members of the derived class[^8].
|
|
| 203 |
In the absence of an *access-specifier* for a base class, `public` is
|
| 204 |
assumed when the derived class is defined with the *class-key* `struct`
|
| 205 |
and `private` is assumed when the class is defined with the *class-key*
|
| 206 |
`class`.
|
| 207 |
|
|
|
|
|
|
|
| 208 |
``` cpp
|
| 209 |
-
class B {
|
| 210 |
-
class D1 : private B {
|
| 211 |
-
class D2 : public B {
|
| 212 |
-
class D3 : B {
|
| 213 |
-
struct D4 : public B {
|
| 214 |
-
struct D5 : private B {
|
| 215 |
-
struct D6 : B {
|
| 216 |
-
class D7 : protected B {
|
| 217 |
-
struct D8 : protected B {
|
| 218 |
```
|
| 219 |
|
| 220 |
Here `B` is a public base of `D2`, `D4`, and `D6`, a private base of
|
| 221 |
`D1`, `D3`, and `D5`, and a protected base of `D7` and `D8`.
|
| 222 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
A member of a private base class might be inaccessible as an inherited
|
| 224 |
member name, but accessible directly. Because of the rules on pointer
|
| 225 |
conversions ([[conv.ptr]]) and explicit casts ([[expr.cast]]), a
|
| 226 |
conversion from a pointer to a derived class to a pointer to an
|
| 227 |
inaccessible base class might be ill-formed if an implicit conversion is
|
|
@@ -250,10 +294,12 @@ void DD::f() {
|
|
| 250 |
::B* bp2 = (::B*)this; // OK with cast
|
| 251 |
bp2->mi = 3; // OK: access through a pointer to B.
|
| 252 |
}
|
| 253 |
```
|
| 254 |
|
|
|
|
|
|
|
| 255 |
A base class `B` of `N` is *accessible* at *R*, if
|
| 256 |
|
| 257 |
- an invented public member of `B` would be a public member of `N`, or
|
| 258 |
- *R* occurs in a member or friend of class `N`, and an invented public
|
| 259 |
member of `B` would be a private or protected member of `N`, or
|
|
@@ -261,10 +307,12 @@ A base class `B` of `N` is *accessible* at *R*, if
|
|
| 261 |
an invented public member of `B` would be a private or protected
|
| 262 |
member of `P`, or
|
| 263 |
- there exists a class `S` such that `B` is a base class of `S`
|
| 264 |
accessible at *R* and `S` is a base class of `N` accessible at *R*.
|
| 265 |
|
|
|
|
|
|
|
| 266 |
``` cpp
|
| 267 |
class B {
|
| 268 |
public:
|
| 269 |
int m;
|
| 270 |
};
|
|
@@ -273,71 +321,85 @@ class S: private B {
|
|
| 273 |
friend class N;
|
| 274 |
};
|
| 275 |
|
| 276 |
class N: private S {
|
| 277 |
void f() {
|
| 278 |
-
B* p = this; // OK because class S satisfies the fourth condition
|
| 279 |
-
//
|
| 280 |
-
// B is an accessible base class of S and S is an accessible
|
| 281 |
// base class of N.
|
| 282 |
}
|
| 283 |
};
|
| 284 |
```
|
| 285 |
|
|
|
|
|
|
|
| 286 |
If a base class is accessible, one can implicitly convert a pointer to a
|
| 287 |
derived class to a pointer to that base class ([[conv.ptr]],
|
| 288 |
-
[[conv.mem]]).
|
|
|
|
|
|
|
| 289 |
implicitly convert an `X*` to a pointer to a private or protected
|
| 290 |
-
immediate base class of `X`.
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
|
| 301 |
- `m` as a member of `N` is public, or
|
| 302 |
- `m` as a member of `N` is private, and *R* occurs in a member or
|
| 303 |
friend of class `N`, or
|
| 304 |
- `m` as a member of `N` is protected, and *R* occurs in a member or
|
| 305 |
-
friend of class `N`, or in a member
|
| 306 |
-
|
| 307 |
-
protected, or
|
| 308 |
- there exists a base class `B` of `N` that is accessible at *R*, and
|
| 309 |
`m` is accessible at *R* when named in class `B`.
|
|
|
|
| 310 |
``` cpp
|
| 311 |
class B;
|
| 312 |
class A {
|
| 313 |
private:
|
| 314 |
int i;
|
| 315 |
friend void f(B*);
|
| 316 |
};
|
| 317 |
class B : public A { };
|
| 318 |
void f(B* p) {
|
| 319 |
-
p->i = 1; // OK: B* can be implicitly converted to A*,
|
| 320 |
-
// and f has access to i in A
|
| 321 |
}
|
| 322 |
```
|
| 323 |
|
| 324 |
-
|
|
|
|
|
|
|
| 325 |
used to access a non-static data member or non-static member function,
|
| 326 |
the reference is ill-formed if the left operand (considered as a pointer
|
| 327 |
in the “`.`” operator case) cannot be implicitly converted to a pointer
|
| 328 |
-
to the naming class of the right operand.
|
| 329 |
-
|
|
|
|
|
|
|
| 330 |
|
| 331 |
## Friends <a id="class.friend">[[class.friend]]</a>
|
| 332 |
|
| 333 |
A friend of a class is a function or class that is given permission to
|
| 334 |
use the private and protected member names from the class. A class
|
| 335 |
specifies its friends, if any, by way of friend declarations. Such
|
| 336 |
declarations give special access rights to the friends, but they do not
|
| 337 |
-
make the nominated friends members of the befriending class.
|
| 338 |
-
|
|
|
|
|
|
|
|
|
|
| 339 |
friends:
|
| 340 |
|
| 341 |
``` cpp
|
| 342 |
class X {
|
| 343 |
int a;
|
|
@@ -354,14 +416,18 @@ void f() {
|
|
| 354 |
friend_set(&obj,10);
|
| 355 |
obj.member_set(10);
|
| 356 |
}
|
| 357 |
```
|
| 358 |
|
|
|
|
|
|
|
| 359 |
Declaring a class to be a friend implies that the names of private and
|
| 360 |
protected members from the class granting friendship can be accessed in
|
| 361 |
the *base-specifier*s and member declarations of the befriended class.
|
| 362 |
|
|
|
|
|
|
|
| 363 |
``` cpp
|
| 364 |
class A {
|
| 365 |
class B { };
|
| 366 |
friend class X;
|
| 367 |
};
|
|
@@ -372,10 +438,14 @@ struct X : A::B { // OK: A::B accessible to friend
|
|
| 372 |
A::B my; // OK: A::B accessible to nested member of friend
|
| 373 |
};
|
| 374 |
};
|
| 375 |
```
|
| 376 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 377 |
``` cpp
|
| 378 |
class X {
|
| 379 |
enum { a=100 };
|
| 380 |
friend class Y;
|
| 381 |
};
|
|
@@ -387,32 +457,42 @@ class Y {
|
|
| 387 |
class Z {
|
| 388 |
int v[X::a]; // error: X::a is private
|
| 389 |
};
|
| 390 |
```
|
| 391 |
|
|
|
|
|
|
|
| 392 |
A class shall not be defined in a friend declaration.
|
| 393 |
|
|
|
|
|
|
|
| 394 |
``` cpp
|
| 395 |
class A {
|
| 396 |
friend class B { }; // error: cannot define class in friend declaration
|
| 397 |
};
|
| 398 |
```
|
| 399 |
|
|
|
|
|
|
|
| 400 |
A `friend` declaration that does not declare a function shall have one
|
| 401 |
of the following forms:
|
| 402 |
|
| 403 |
``` bnf
|
| 404 |
'friend' elaborated-type-specifier ';'
|
| 405 |
'friend' simple-type-specifier ';'
|
| 406 |
'friend' typename-specifier ';'
|
| 407 |
```
|
| 408 |
|
| 409 |
-
A `friend` declaration may be the *declaration* in a
|
| 410 |
-
*template-declaration* (Clause [[temp]],
|
| 411 |
-
|
| 412 |
-
|
| 413 |
-
declaration
|
|
|
|
|
|
|
|
|
|
|
|
|
| 414 |
|
| 415 |
``` cpp
|
| 416 |
class C;
|
| 417 |
typedef C Ct;
|
| 418 |
|
|
@@ -432,41 +512,51 @@ template <typename T> class R {
|
|
| 432 |
|
| 433 |
R<C> rc; // class C is a friend of R<C>
|
| 434 |
R<int> Ri; // OK: "friend int;" is ignored
|
| 435 |
```
|
| 436 |
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
|
|
|
|
|
|
| 440 |
|
| 441 |
When a `friend` declaration refers to an overloaded name or operator,
|
| 442 |
only the function specified by the parameter types becomes a friend. A
|
| 443 |
member function of a class `X` can be a friend of a class `Y`.
|
| 444 |
|
|
|
|
|
|
|
| 445 |
``` cpp
|
| 446 |
class Y {
|
| 447 |
friend char* X::foo(int);
|
| 448 |
friend X::X(char); // constructors can be friends
|
| 449 |
friend X::~X(); // destructors can be friends
|
| 450 |
};
|
| 451 |
```
|
| 452 |
|
|
|
|
|
|
|
| 453 |
A function can be defined in a friend declaration of a class if and only
|
| 454 |
if the class is a non-local class ([[class.local]]), the function name
|
| 455 |
is unqualified, and the function has namespace scope.
|
| 456 |
|
|
|
|
|
|
|
| 457 |
``` cpp
|
| 458 |
class M {
|
| 459 |
friend void f() { } // definition of global f, a friend of M,
|
| 460 |
// not the definition of a member function
|
| 461 |
};
|
| 462 |
```
|
| 463 |
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
|
|
|
|
|
|
| 468 |
|
| 469 |
No *storage-class-specifier* shall appear in the *decl-specifier-seq* of
|
| 470 |
a friend declaration.
|
| 471 |
|
| 472 |
A name nominated by a friend declaration shall be accessible in the
|
|
@@ -475,10 +565,12 @@ friend declaration is the same whether the friend declaration appears in
|
|
| 475 |
the `private`, `protected` or `public` ([[class.mem]]) portion of the
|
| 476 |
class *member-specification*.
|
| 477 |
|
| 478 |
Friendship is neither inherited nor transitive.
|
| 479 |
|
|
|
|
|
|
|
| 480 |
``` cpp
|
| 481 |
class A {
|
| 482 |
friend class B;
|
| 483 |
int a;
|
| 484 |
};
|
|
@@ -487,33 +579,35 @@ class B {
|
|
| 487 |
friend class C;
|
| 488 |
};
|
| 489 |
|
| 490 |
class C {
|
| 491 |
void f(A* p) {
|
| 492 |
-
p->a++; // error: C is not a friend of A
|
| 493 |
-
// despite being a friend of a friend
|
| 494 |
}
|
| 495 |
};
|
| 496 |
|
| 497 |
class D : public B {
|
| 498 |
void f(A* p) {
|
| 499 |
-
p->a++; // error: D is not a friend of A
|
| 500 |
-
// despite being derived from a friend
|
| 501 |
}
|
| 502 |
};
|
| 503 |
```
|
| 504 |
|
|
|
|
|
|
|
| 505 |
If a friend declaration appears in a local class ([[class.local]]) and
|
| 506 |
the name specified is an unqualified name, a prior declaration is looked
|
| 507 |
up without considering scopes that are outside the innermost enclosing
|
| 508 |
non-class scope. For a friend function declaration, if there is no prior
|
| 509 |
declaration, the program is ill-formed. For a friend class declaration,
|
| 510 |
if there is no prior declaration, the class that is specified belongs to
|
| 511 |
the innermost enclosing non-class scope, but if it is subsequently
|
| 512 |
referenced, its name is not found by name lookup until a matching
|
| 513 |
declaration is provided in the innermost enclosing non-class scope.
|
| 514 |
|
|
|
|
|
|
|
| 515 |
``` cpp
|
| 516 |
class X;
|
| 517 |
void a();
|
| 518 |
void f() {
|
| 519 |
class Y;
|
|
@@ -529,10 +623,12 @@ void f() {
|
|
| 529 |
X* px; // OK, but ::X is found
|
| 530 |
Z* pz; // error, no Z is found
|
| 531 |
}
|
| 532 |
```
|
| 533 |
|
|
|
|
|
|
|
| 534 |
## Protected member access <a id="class.protected">[[class.protected]]</a>
|
| 535 |
|
| 536 |
An additional access check beyond those described earlier in Clause
|
| 537 |
[[class.access]] is applied when a non-static data member or non-static
|
| 538 |
member function is a protected member of its naming class (
|
|
@@ -542,10 +638,12 @@ some class `C`. If the access is to form a pointer to member (
|
|
| 542 |
[[expr.unary.op]]), the *nested-name-specifier* shall denote `C` or a
|
| 543 |
class derived from `C`. All other accesses involve a (possibly implicit)
|
| 544 |
object expression ([[expr.ref]]). In this case, the class of the object
|
| 545 |
expression shall be `C` or a class derived from `C`.
|
| 546 |
|
|
|
|
|
|
|
| 547 |
``` cpp
|
| 548 |
class B {
|
| 549 |
protected:
|
| 550 |
int i;
|
| 551 |
static int j;
|
|
@@ -561,15 +659,14 @@ class D2 : public B {
|
|
| 561 |
|
| 562 |
void fr(B* pb, D1* p1, D2* p2) {
|
| 563 |
pb->i = 1; // ill-formed
|
| 564 |
p1->i = 2; // ill-formed
|
| 565 |
p2->i = 3; // OK (access through a D2)
|
| 566 |
-
p2->B::i = 4; // OK (access through a D2, even though
|
| 567 |
-
// naming class is B)
|
| 568 |
int B::* pmi_B = &B::i; // ill-formed
|
| 569 |
int B::* pmi_B2 = &D2::i; // OK (type of &D2::i is int B::*)
|
| 570 |
-
B::j = 5; //
|
| 571 |
D2::j = 6; // OK (because refers to static member)
|
| 572 |
}
|
| 573 |
|
| 574 |
void D2::mem(B* pb, D1* p1) {
|
| 575 |
pb->i = 1; // ill-formed
|
|
@@ -587,16 +684,20 @@ void g(B* pb, D1* p1, D2* p2) {
|
|
| 587 |
p1->i = 2; // ill-formed
|
| 588 |
p2->i = 3; // ill-formed
|
| 589 |
}
|
| 590 |
```
|
| 591 |
|
|
|
|
|
|
|
| 592 |
## Access to virtual functions <a id="class.access.virt">[[class.access.virt]]</a>
|
| 593 |
|
| 594 |
The access rules (Clause [[class.access]]) for a virtual function are
|
| 595 |
determined by its declaration and are not affected by the rules for a
|
| 596 |
function that later overrides it.
|
| 597 |
|
|
|
|
|
|
|
| 598 |
``` cpp
|
| 599 |
class B {
|
| 600 |
public:
|
| 601 |
virtual int f();
|
| 602 |
};
|
|
@@ -609,26 +710,29 @@ private:
|
|
| 609 |
void f() {
|
| 610 |
D d;
|
| 611 |
B* pb = &d;
|
| 612 |
D* pd = &d;
|
| 613 |
|
| 614 |
-
pb->f(); // OK: B::f() is public,
|
| 615 |
-
// D::f() is invoked
|
| 616 |
pd->f(); // error: D::f() is private
|
| 617 |
}
|
| 618 |
```
|
| 619 |
|
|
|
|
|
|
|
| 620 |
Access is checked at the call point using the type of the expression
|
| 621 |
used to denote the object for which the member function is called (`B*`
|
| 622 |
in the example above). The access of the member function in the class in
|
| 623 |
which it was defined (`D` in the example above) is in general not known.
|
| 624 |
|
| 625 |
## Multiple access <a id="class.paths">[[class.paths]]</a>
|
| 626 |
|
| 627 |
If a name can be reached by several paths through a multiple inheritance
|
| 628 |
graph, the access is that of the path that gives most access.
|
| 629 |
|
|
|
|
|
|
|
| 630 |
``` cpp
|
| 631 |
class W { public: void f(); };
|
| 632 |
class A : private virtual W { };
|
| 633 |
class B : public virtual W { };
|
| 634 |
class C : public A, public B {
|
|
@@ -637,17 +741,21 @@ class C : public A, public B {
|
|
| 637 |
```
|
| 638 |
|
| 639 |
Since `W::f()` is available to `C::f()` along the public path through
|
| 640 |
`B`, access is allowed.
|
| 641 |
|
|
|
|
|
|
|
| 642 |
## Nested classes <a id="class.access.nest">[[class.access.nest]]</a>
|
| 643 |
|
| 644 |
A nested class is a member and as such has the same access rights as any
|
| 645 |
other member. The members of an enclosing class have no special access
|
| 646 |
to members of a nested class; the usual access rules (Clause
|
| 647 |
[[class.access]]) shall be obeyed.
|
| 648 |
|
|
|
|
|
|
|
| 649 |
``` cpp
|
| 650 |
class E {
|
| 651 |
int x;
|
| 652 |
class B { };
|
| 653 |
|
|
@@ -663,22 +771,27 @@ class E {
|
|
| 663 |
return p->y; // error: I::y is private
|
| 664 |
}
|
| 665 |
};
|
| 666 |
```
|
| 667 |
|
|
|
|
|
|
|
| 668 |
<!-- Link reference definitions -->
|
|
|
|
| 669 |
[basic.def.odr]: basic.md#basic.def.odr
|
| 670 |
[basic.fundamental]: basic.md#basic.fundamental
|
|
|
|
| 671 |
[basic.link]: basic.md#basic.link
|
| 672 |
[basic.lookup]: basic.md#basic.lookup
|
| 673 |
[basic.lookup.elab]: basic.md#basic.lookup.elab
|
| 674 |
[basic.lookup.qual]: basic.md#basic.lookup.qual
|
| 675 |
[basic.lookup.unqual]: basic.md#basic.lookup.unqual
|
| 676 |
[basic.scope]: basic.md#basic.scope
|
| 677 |
[basic.scope.class]: basic.md#basic.scope.class
|
| 678 |
[basic.scope.hiding]: basic.md#basic.scope.hiding
|
| 679 |
-
[basic.start.
|
|
|
|
| 680 |
[basic.start.term]: basic.md#basic.start.term
|
| 681 |
[basic.stc]: basic.md#basic.stc
|
| 682 |
[basic.types]: basic.md#basic.types
|
| 683 |
[c.strings]: strings.md#c.strings
|
| 684 |
[class]: #class
|
|
@@ -695,11 +808,10 @@ class E {
|
|
| 695 |
[class.ctor]: special.md#class.ctor
|
| 696 |
[class.derived]: #class.derived
|
| 697 |
[class.dtor]: special.md#class.dtor
|
| 698 |
[class.free]: special.md#class.free
|
| 699 |
[class.friend]: #class.friend
|
| 700 |
-
[class.inhctor]: special.md#class.inhctor
|
| 701 |
[class.local]: #class.local
|
| 702 |
[class.mem]: #class.mem
|
| 703 |
[class.member.lookup]: #class.member.lookup
|
| 704 |
[class.mfct]: #class.mfct
|
| 705 |
[class.mfct.non-static]: #class.mfct.non-static
|
|
@@ -712,10 +824,11 @@ class E {
|
|
| 712 |
[class.static]: #class.static
|
| 713 |
[class.static.data]: #class.static.data
|
| 714 |
[class.static.mfct]: #class.static.mfct
|
| 715 |
[class.this]: #class.this
|
| 716 |
[class.union]: #class.union
|
|
|
|
| 717 |
[class.virtual]: #class.virtual
|
| 718 |
[conv.mem]: conv.md#conv.mem
|
| 719 |
[conv.ptr]: conv.md#conv.ptr
|
| 720 |
[dcl.enum]: dcl.md#dcl.enum
|
| 721 |
[dcl.fct]: dcl.md#dcl.fct
|
|
@@ -723,22 +836,29 @@ class E {
|
|
| 723 |
[dcl.fct.def.delete]: dcl.md#dcl.fct.def.delete
|
| 724 |
[dcl.fct.default]: dcl.md#dcl.fct.default
|
| 725 |
[dcl.fct.spec]: dcl.md#dcl.fct.spec
|
| 726 |
[dcl.init.aggr]: dcl.md#dcl.init.aggr
|
| 727 |
[dcl.init.ref]: dcl.md#dcl.init.ref
|
|
|
|
| 728 |
[dcl.stc]: dcl.md#dcl.stc
|
| 729 |
[dcl.type.cv]: dcl.md#dcl.type.cv
|
| 730 |
[dcl.type.elab]: dcl.md#dcl.type.elab
|
| 731 |
[dcl.typedef]: dcl.md#dcl.typedef
|
|
|
|
|
|
|
| 732 |
[expr.call]: expr.md#expr.call
|
| 733 |
[expr.cast]: expr.md#expr.cast
|
| 734 |
[expr.const]: expr.md#expr.const
|
| 735 |
[expr.eq]: expr.md#expr.eq
|
| 736 |
[expr.prim]: expr.md#expr.prim
|
| 737 |
-
[expr.prim.
|
| 738 |
[expr.ref]: expr.md#expr.ref
|
|
|
|
| 739 |
[expr.unary.op]: expr.md#expr.unary.op
|
|
|
|
|
|
|
|
|
|
| 740 |
[intro.object]: intro.md#intro.object
|
| 741 |
[namespace.def]: dcl.md#namespace.def
|
| 742 |
[namespace.udecl]: dcl.md#namespace.udecl
|
| 743 |
[over]: over.md#over
|
| 744 |
[over.ass]: over.md#over.ass
|
|
@@ -748,12 +868,14 @@ class E {
|
|
| 748 |
[over.match.funcs]: over.md#over.match.funcs
|
| 749 |
[over.oper]: over.md#over.oper
|
| 750 |
[string.classes]: strings.md#string.classes
|
| 751 |
[temp]: temp.md#temp
|
| 752 |
[temp.arg]: temp.md#temp.arg
|
|
|
|
| 753 |
[temp.friend]: temp.md#temp.friend
|
| 754 |
[temp.inst]: temp.md#temp.inst
|
|
|
|
| 755 |
[temp.param]: temp.md#temp.param
|
| 756 |
[temp.spec]: temp.md#temp.spec
|
| 757 |
[temp.variadic]: temp.md#temp.variadic
|
| 758 |
|
| 759 |
[^1]: Base class subobjects are not so constrained.
|
|
|
|
| 16 |
|
| 17 |
Members of a class defined with the keyword `class` are `private` by
|
| 18 |
default. Members of a class defined with the keywords `struct` or
|
| 19 |
`union` are `public` by default.
|
| 20 |
|
| 21 |
+
[*Example 1*:
|
| 22 |
+
|
| 23 |
``` cpp
|
| 24 |
class X {
|
| 25 |
int a; // X::a is private by default
|
| 26 |
};
|
| 27 |
|
| 28 |
struct S {
|
| 29 |
int a; // S::a is public by default
|
| 30 |
};
|
| 31 |
```
|
| 32 |
|
| 33 |
+
— *end example*]
|
| 34 |
+
|
| 35 |
Access control is applied uniformly to all names, whether the names are
|
| 36 |
+
referred to from declarations or expressions.
|
| 37 |
+
|
| 38 |
+
[*Note 1*: Access control applies to names nominated by `friend`
|
| 39 |
+
declarations ([[class.friend]]) and *using-declaration*s (
|
| 40 |
+
[[namespace.udecl]]). — *end note*]
|
| 41 |
+
|
| 42 |
+
In the case of overloaded function names, access control is applied to
|
| 43 |
+
the function selected by overload resolution.
|
| 44 |
+
|
| 45 |
+
[*Note 2*:
|
| 46 |
+
|
| 47 |
+
Because access control applies to names, if access control is applied to
|
| 48 |
+
a typedef name, only the accessibility of the typedef name itself is
|
| 49 |
+
considered. The accessibility of the entity referred to by the typedef
|
| 50 |
+
is not considered. For example,
|
| 51 |
|
| 52 |
``` cpp
|
| 53 |
class A {
|
| 54 |
class B { };
|
| 55 |
public:
|
|
|
|
| 60 |
A::BB x; // OK, typedef name A::BB is public
|
| 61 |
A::B y; // access error, A::B is private
|
| 62 |
}
|
| 63 |
```
|
| 64 |
|
| 65 |
+
— *end note*]
|
| 66 |
+
|
| 67 |
It should be noted that it is *access* to members and base classes that
|
| 68 |
is controlled, not their *visibility*. Names of members are still
|
| 69 |
visible, and implicit conversions to base classes are still considered,
|
| 70 |
when those members and base classes are inaccessible. The interpretation
|
| 71 |
of a given construct is established without regard to access control. If
|
|
|
|
| 74 |
|
| 75 |
All access controls in Clause [[class.access]] affect the ability to
|
| 76 |
access a class member name from the declaration of a particular entity,
|
| 77 |
including parts of the declaration preceding the name of the entity
|
| 78 |
being declared and, if the entity is a class, the definitions of members
|
| 79 |
+
of the class appearing outside the class’s *member-specification*.
|
| 80 |
+
|
| 81 |
+
[*Note 3*: This access also applies to implicit references to
|
| 82 |
+
constructors, conversion functions, and destructors. — *end note*]
|
| 83 |
+
|
| 84 |
+
[*Example 2*:
|
| 85 |
|
| 86 |
``` cpp
|
| 87 |
class A {
|
| 88 |
typedef int I; // private member
|
| 89 |
I f();
|
|
|
|
| 112 |
is as the return type of a member of class `A`. Similarly, the use of
|
| 113 |
`A::B` as a *base-specifier* is well-formed because `D` is derived from
|
| 114 |
`A`, so checking of *base-specifier*s must be deferred until the entire
|
| 115 |
*base-specifier-list* has been seen.
|
| 116 |
|
| 117 |
+
— *end example*]
|
| 118 |
+
|
| 119 |
The names in a default argument ([[dcl.fct.default]]) are bound at the
|
| 120 |
point of declaration, and access is checked at that point rather than at
|
| 121 |
any points of use of the default argument. Access checking for default
|
| 122 |
arguments in function templates and in member functions of class
|
| 123 |
templates is performed as described in [[temp.inst]].
|
| 124 |
|
| 125 |
The names in a default *template-argument* ([[temp.param]]) have their
|
| 126 |
access checked in the context in which they appear rather than at any
|
| 127 |
points of use of the default *template-argument*.
|
| 128 |
|
| 129 |
+
[*Example 3*:
|
| 130 |
+
|
| 131 |
``` cpp
|
| 132 |
class B { };
|
| 133 |
template <class T> class C {
|
| 134 |
protected:
|
| 135 |
typedef T TT;
|
|
|
|
| 139 |
class D : public U { };
|
| 140 |
|
| 141 |
D <C<B> >* d; // access error, C::TT is protected
|
| 142 |
```
|
| 143 |
|
| 144 |
+
— *end example*]
|
| 145 |
+
|
| 146 |
## Access specifiers <a id="class.access.spec">[[class.access.spec]]</a>
|
| 147 |
|
| 148 |
Member declarations can be labeled by an *access-specifier* (Clause
|
| 149 |
[[class.derived]]):
|
| 150 |
|
| 151 |
An *access-specifier* specifies the access rules for members following
|
| 152 |
it until the end of the class or until another *access-specifier* is
|
| 153 |
encountered.
|
| 154 |
|
| 155 |
+
[*Example 1*:
|
| 156 |
+
|
| 157 |
``` cpp
|
| 158 |
class X {
|
| 159 |
int a; // X::a is private by default: class used
|
| 160 |
public:
|
| 161 |
int b; // X::b is public
|
| 162 |
int c; // X::c is public
|
| 163 |
};
|
| 164 |
```
|
| 165 |
|
| 166 |
+
— *end example*]
|
| 167 |
+
|
| 168 |
Any number of access specifiers is allowed and no particular order is
|
| 169 |
required.
|
| 170 |
|
| 171 |
+
[*Example 2*:
|
| 172 |
+
|
| 173 |
``` cpp
|
| 174 |
struct S {
|
| 175 |
int a; // S::a is public by default: struct used
|
| 176 |
protected:
|
| 177 |
int b; // S::b is protected
|
|
|
|
| 180 |
public:
|
| 181 |
int d; // S::d is public
|
| 182 |
};
|
| 183 |
```
|
| 184 |
|
| 185 |
+
— *end example*]
|
| 186 |
+
|
| 187 |
+
[*Note 1*: The effect of access control on the order of allocation of
|
| 188 |
+
data members is described in [[class.mem]]. — *end note*]
|
| 189 |
|
| 190 |
When a member is redeclared within its class definition, the access
|
| 191 |
specified at its redeclaration shall be the same as at its initial
|
| 192 |
declaration.
|
| 193 |
|
| 194 |
+
[*Example 3*:
|
| 195 |
+
|
| 196 |
``` cpp
|
| 197 |
struct S {
|
| 198 |
class A;
|
| 199 |
enum E : int;
|
| 200 |
private:
|
| 201 |
class A { }; // error: cannot change access
|
| 202 |
enum E: int { e0 }; // error: cannot change access
|
| 203 |
};
|
| 204 |
```
|
| 205 |
|
| 206 |
+
— *end example*]
|
| 207 |
+
|
| 208 |
+
[*Note 2*: In a derived class, the lookup of a base class name will
|
| 209 |
+
find the injected-class-name instead of the name of the base class in
|
| 210 |
+
the scope in which it was declared. The injected-class-name might be
|
| 211 |
+
less accessible than the name of the base class in the scope in which it
|
| 212 |
+
was declared. — *end note*]
|
| 213 |
+
|
| 214 |
+
[*Example 4*:
|
| 215 |
|
| 216 |
``` cpp
|
| 217 |
class A { };
|
| 218 |
class B : private A { };
|
| 219 |
class C : public B {
|
| 220 |
A* p; // error: injected-class-name A is inaccessible
|
| 221 |
::A* q; // OK
|
| 222 |
};
|
| 223 |
```
|
| 224 |
|
| 225 |
+
— *end example*]
|
| 226 |
+
|
| 227 |
## Accessibility of base classes and base class members <a id="class.access.base">[[class.access.base]]</a>
|
| 228 |
|
| 229 |
If a class is declared to be a base class (Clause [[class.derived]])
|
| 230 |
for another class using the `public` access specifier, the `public`
|
| 231 |
members of the base class are accessible as `public` members of the
|
|
|
|
| 241 |
In the absence of an *access-specifier* for a base class, `public` is
|
| 242 |
assumed when the derived class is defined with the *class-key* `struct`
|
| 243 |
and `private` is assumed when the class is defined with the *class-key*
|
| 244 |
`class`.
|
| 245 |
|
| 246 |
+
[*Example 1*:
|
| 247 |
+
|
| 248 |
``` cpp
|
| 249 |
+
class B { ... };
|
| 250 |
+
class D1 : private B { ... };
|
| 251 |
+
class D2 : public B { ... };
|
| 252 |
+
class D3 : B { ... }; // B private by default
|
| 253 |
+
struct D4 : public B { ... };
|
| 254 |
+
struct D5 : private B { ... };
|
| 255 |
+
struct D6 : B { ... }; // B public by default
|
| 256 |
+
class D7 : protected B { ... };
|
| 257 |
+
struct D8 : protected B { ... };
|
| 258 |
```
|
| 259 |
|
| 260 |
Here `B` is a public base of `D2`, `D4`, and `D6`, a private base of
|
| 261 |
`D1`, `D3`, and `D5`, and a protected base of `D7` and `D8`.
|
| 262 |
|
| 263 |
+
— *end example*]
|
| 264 |
+
|
| 265 |
+
[*Note 1*:
|
| 266 |
+
|
| 267 |
A member of a private base class might be inaccessible as an inherited
|
| 268 |
member name, but accessible directly. Because of the rules on pointer
|
| 269 |
conversions ([[conv.ptr]]) and explicit casts ([[expr.cast]]), a
|
| 270 |
conversion from a pointer to a derived class to a pointer to an
|
| 271 |
inaccessible base class might be ill-formed if an implicit conversion is
|
|
|
|
| 294 |
::B* bp2 = (::B*)this; // OK with cast
|
| 295 |
bp2->mi = 3; // OK: access through a pointer to B.
|
| 296 |
}
|
| 297 |
```
|
| 298 |
|
| 299 |
+
— *end note*]
|
| 300 |
+
|
| 301 |
A base class `B` of `N` is *accessible* at *R*, if
|
| 302 |
|
| 303 |
- an invented public member of `B` would be a public member of `N`, or
|
| 304 |
- *R* occurs in a member or friend of class `N`, and an invented public
|
| 305 |
member of `B` would be a private or protected member of `N`, or
|
|
|
|
| 307 |
an invented public member of `B` would be a private or protected
|
| 308 |
member of `P`, or
|
| 309 |
- there exists a class `S` such that `B` is a base class of `S`
|
| 310 |
accessible at *R* and `S` is a base class of `N` accessible at *R*.
|
| 311 |
|
| 312 |
+
[*Example 2*:
|
| 313 |
+
|
| 314 |
``` cpp
|
| 315 |
class B {
|
| 316 |
public:
|
| 317 |
int m;
|
| 318 |
};
|
|
|
|
| 321 |
friend class N;
|
| 322 |
};
|
| 323 |
|
| 324 |
class N: private S {
|
| 325 |
void f() {
|
| 326 |
+
B* p = this; // OK because class S satisfies the fourth condition above: B is a base class of N
|
| 327 |
+
// accessible in f() because B is an accessible base class of S and S is an accessible
|
|
|
|
| 328 |
// base class of N.
|
| 329 |
}
|
| 330 |
};
|
| 331 |
```
|
| 332 |
|
| 333 |
+
— *end example*]
|
| 334 |
+
|
| 335 |
If a base class is accessible, one can implicitly convert a pointer to a
|
| 336 |
derived class to a pointer to that base class ([[conv.ptr]],
|
| 337 |
+
[[conv.mem]]).
|
| 338 |
+
|
| 339 |
+
[*Note 2*: It follows that members and friends of a class `X` can
|
| 340 |
implicitly convert an `X*` to a pointer to a private or protected
|
| 341 |
+
immediate base class of `X`. — *end note*]
|
| 342 |
+
|
| 343 |
+
The access to a member is affected by the class in which the member is
|
| 344 |
+
named. This naming class is the class in which the member name was
|
| 345 |
+
looked up and found.
|
| 346 |
+
|
| 347 |
+
[*Note 3*: This class can be explicit, e.g., when a *qualified-id* is
|
| 348 |
+
used, or implicit, e.g., when a class member access operator (
|
| 349 |
+
[[expr.ref]]) is used (including cases where an implicit “`this->`” is
|
| 350 |
+
added). If both a class member access operator and a *qualified-id* are
|
| 351 |
+
used to name the member (as in `p->T::m`), the class naming the member
|
| 352 |
+
is the class denoted by the *nested-name-specifier* of the
|
| 353 |
+
*qualified-id* (that is, `T`). — *end note*]
|
| 354 |
+
|
| 355 |
+
A member `m` is accessible at the point *R* when named in class `N` if
|
| 356 |
|
| 357 |
- `m` as a member of `N` is public, or
|
| 358 |
- `m` as a member of `N` is private, and *R* occurs in a member or
|
| 359 |
friend of class `N`, or
|
| 360 |
- `m` as a member of `N` is protected, and *R* occurs in a member or
|
| 361 |
+
friend of class `N`, or in a member of a class `P` derived from `N`,
|
| 362 |
+
where `m` as a member of `P` is public, private, or protected, or
|
|
|
|
| 363 |
- there exists a base class `B` of `N` that is accessible at *R*, and
|
| 364 |
`m` is accessible at *R* when named in class `B`.
|
| 365 |
+
\[*Example 3*:
|
| 366 |
``` cpp
|
| 367 |
class B;
|
| 368 |
class A {
|
| 369 |
private:
|
| 370 |
int i;
|
| 371 |
friend void f(B*);
|
| 372 |
};
|
| 373 |
class B : public A { };
|
| 374 |
void f(B* p) {
|
| 375 |
+
p->i = 1; // OK: B* can be implicitly converted to A*, and f has access to i in A
|
|
|
|
| 376 |
}
|
| 377 |
```
|
| 378 |
|
| 379 |
+
— *end example*]
|
| 380 |
+
|
| 381 |
+
If a class member access operator, including an implicit “`this->`”, is
|
| 382 |
used to access a non-static data member or non-static member function,
|
| 383 |
the reference is ill-formed if the left operand (considered as a pointer
|
| 384 |
in the “`.`” operator case) cannot be implicitly converted to a pointer
|
| 385 |
+
to the naming class of the right operand.
|
| 386 |
+
|
| 387 |
+
[*Note 4*: This requirement is in addition to the requirement that the
|
| 388 |
+
member be accessible as named. — *end note*]
|
| 389 |
|
| 390 |
## Friends <a id="class.friend">[[class.friend]]</a>
|
| 391 |
|
| 392 |
A friend of a class is a function or class that is given permission to
|
| 393 |
use the private and protected member names from the class. A class
|
| 394 |
specifies its friends, if any, by way of friend declarations. Such
|
| 395 |
declarations give special access rights to the friends, but they do not
|
| 396 |
+
make the nominated friends members of the befriending class.
|
| 397 |
+
|
| 398 |
+
[*Example 1*:
|
| 399 |
+
|
| 400 |
+
The following example illustrates the differences between members and
|
| 401 |
friends:
|
| 402 |
|
| 403 |
``` cpp
|
| 404 |
class X {
|
| 405 |
int a;
|
|
|
|
| 416 |
friend_set(&obj,10);
|
| 417 |
obj.member_set(10);
|
| 418 |
}
|
| 419 |
```
|
| 420 |
|
| 421 |
+
— *end example*]
|
| 422 |
+
|
| 423 |
Declaring a class to be a friend implies that the names of private and
|
| 424 |
protected members from the class granting friendship can be accessed in
|
| 425 |
the *base-specifier*s and member declarations of the befriended class.
|
| 426 |
|
| 427 |
+
[*Example 2*:
|
| 428 |
+
|
| 429 |
``` cpp
|
| 430 |
class A {
|
| 431 |
class B { };
|
| 432 |
friend class X;
|
| 433 |
};
|
|
|
|
| 438 |
A::B my; // OK: A::B accessible to nested member of friend
|
| 439 |
};
|
| 440 |
};
|
| 441 |
```
|
| 442 |
|
| 443 |
+
— *end example*]
|
| 444 |
+
|
| 445 |
+
[*Example 3*:
|
| 446 |
+
|
| 447 |
``` cpp
|
| 448 |
class X {
|
| 449 |
enum { a=100 };
|
| 450 |
friend class Y;
|
| 451 |
};
|
|
|
|
| 457 |
class Z {
|
| 458 |
int v[X::a]; // error: X::a is private
|
| 459 |
};
|
| 460 |
```
|
| 461 |
|
| 462 |
+
— *end example*]
|
| 463 |
+
|
| 464 |
A class shall not be defined in a friend declaration.
|
| 465 |
|
| 466 |
+
[*Example 4*:
|
| 467 |
+
|
| 468 |
``` cpp
|
| 469 |
class A {
|
| 470 |
friend class B { }; // error: cannot define class in friend declaration
|
| 471 |
};
|
| 472 |
```
|
| 473 |
|
| 474 |
+
— *end example*]
|
| 475 |
+
|
| 476 |
A `friend` declaration that does not declare a function shall have one
|
| 477 |
of the following forms:
|
| 478 |
|
| 479 |
``` bnf
|
| 480 |
'friend' elaborated-type-specifier ';'
|
| 481 |
'friend' simple-type-specifier ';'
|
| 482 |
'friend' typename-specifier ';'
|
| 483 |
```
|
| 484 |
|
| 485 |
+
[*Note 1*: A `friend` declaration may be the *declaration* in a
|
| 486 |
+
*template-declaration* (Clause [[temp]],
|
| 487 |
+
[[temp.friend]]). — *end note*]
|
| 488 |
+
|
| 489 |
+
If the type specifier in a `friend` declaration designates a (possibly
|
| 490 |
+
cv-qualified) class type, that class is declared as a friend; otherwise,
|
| 491 |
+
the `friend` declaration is ignored.
|
| 492 |
+
|
| 493 |
+
[*Example 5*:
|
| 494 |
|
| 495 |
``` cpp
|
| 496 |
class C;
|
| 497 |
typedef C Ct;
|
| 498 |
|
|
|
|
| 512 |
|
| 513 |
R<C> rc; // class C is a friend of R<C>
|
| 514 |
R<int> Ri; // OK: "friend int;" is ignored
|
| 515 |
```
|
| 516 |
|
| 517 |
+
— *end example*]
|
| 518 |
+
|
| 519 |
+
A function first declared in a friend declaration has the linkage of the
|
| 520 |
+
namespace of which it is a member ([[basic.link]]). Otherwise, the
|
| 521 |
+
function retains its previous linkage ([[dcl.stc]]).
|
| 522 |
|
| 523 |
When a `friend` declaration refers to an overloaded name or operator,
|
| 524 |
only the function specified by the parameter types becomes a friend. A
|
| 525 |
member function of a class `X` can be a friend of a class `Y`.
|
| 526 |
|
| 527 |
+
[*Example 6*:
|
| 528 |
+
|
| 529 |
``` cpp
|
| 530 |
class Y {
|
| 531 |
friend char* X::foo(int);
|
| 532 |
friend X::X(char); // constructors can be friends
|
| 533 |
friend X::~X(); // destructors can be friends
|
| 534 |
};
|
| 535 |
```
|
| 536 |
|
| 537 |
+
— *end example*]
|
| 538 |
+
|
| 539 |
A function can be defined in a friend declaration of a class if and only
|
| 540 |
if the class is a non-local class ([[class.local]]), the function name
|
| 541 |
is unqualified, and the function has namespace scope.
|
| 542 |
|
| 543 |
+
[*Example 7*:
|
| 544 |
+
|
| 545 |
``` cpp
|
| 546 |
class M {
|
| 547 |
friend void f() { } // definition of global f, a friend of M,
|
| 548 |
// not the definition of a member function
|
| 549 |
};
|
| 550 |
```
|
| 551 |
|
| 552 |
+
— *end example*]
|
| 553 |
+
|
| 554 |
+
Such a function is implicitly an inline function ([[dcl.inline]]). A
|
| 555 |
+
`friend` function defined in a class is in the (lexical) scope of the
|
| 556 |
+
class in which it is defined. A friend function defined outside the
|
| 557 |
+
class is not ([[basic.lookup.unqual]]).
|
| 558 |
|
| 559 |
No *storage-class-specifier* shall appear in the *decl-specifier-seq* of
|
| 560 |
a friend declaration.
|
| 561 |
|
| 562 |
A name nominated by a friend declaration shall be accessible in the
|
|
|
|
| 565 |
the `private`, `protected` or `public` ([[class.mem]]) portion of the
|
| 566 |
class *member-specification*.
|
| 567 |
|
| 568 |
Friendship is neither inherited nor transitive.
|
| 569 |
|
| 570 |
+
[*Example 8*:
|
| 571 |
+
|
| 572 |
``` cpp
|
| 573 |
class A {
|
| 574 |
friend class B;
|
| 575 |
int a;
|
| 576 |
};
|
|
|
|
| 579 |
friend class C;
|
| 580 |
};
|
| 581 |
|
| 582 |
class C {
|
| 583 |
void f(A* p) {
|
| 584 |
+
p->a++; // error: C is not a friend of A despite being a friend of a friend
|
|
|
|
| 585 |
}
|
| 586 |
};
|
| 587 |
|
| 588 |
class D : public B {
|
| 589 |
void f(A* p) {
|
| 590 |
+
p->a++; // error: D is not a friend of A despite being derived from a friend
|
|
|
|
| 591 |
}
|
| 592 |
};
|
| 593 |
```
|
| 594 |
|
| 595 |
+
— *end example*]
|
| 596 |
+
|
| 597 |
If a friend declaration appears in a local class ([[class.local]]) and
|
| 598 |
the name specified is an unqualified name, a prior declaration is looked
|
| 599 |
up without considering scopes that are outside the innermost enclosing
|
| 600 |
non-class scope. For a friend function declaration, if there is no prior
|
| 601 |
declaration, the program is ill-formed. For a friend class declaration,
|
| 602 |
if there is no prior declaration, the class that is specified belongs to
|
| 603 |
the innermost enclosing non-class scope, but if it is subsequently
|
| 604 |
referenced, its name is not found by name lookup until a matching
|
| 605 |
declaration is provided in the innermost enclosing non-class scope.
|
| 606 |
|
| 607 |
+
[*Example 9*:
|
| 608 |
+
|
| 609 |
``` cpp
|
| 610 |
class X;
|
| 611 |
void a();
|
| 612 |
void f() {
|
| 613 |
class Y;
|
|
|
|
| 623 |
X* px; // OK, but ::X is found
|
| 624 |
Z* pz; // error, no Z is found
|
| 625 |
}
|
| 626 |
```
|
| 627 |
|
| 628 |
+
— *end example*]
|
| 629 |
+
|
| 630 |
## Protected member access <a id="class.protected">[[class.protected]]</a>
|
| 631 |
|
| 632 |
An additional access check beyond those described earlier in Clause
|
| 633 |
[[class.access]] is applied when a non-static data member or non-static
|
| 634 |
member function is a protected member of its naming class (
|
|
|
|
| 638 |
[[expr.unary.op]]), the *nested-name-specifier* shall denote `C` or a
|
| 639 |
class derived from `C`. All other accesses involve a (possibly implicit)
|
| 640 |
object expression ([[expr.ref]]). In this case, the class of the object
|
| 641 |
expression shall be `C` or a class derived from `C`.
|
| 642 |
|
| 643 |
+
[*Example 1*:
|
| 644 |
+
|
| 645 |
``` cpp
|
| 646 |
class B {
|
| 647 |
protected:
|
| 648 |
int i;
|
| 649 |
static int j;
|
|
|
|
| 659 |
|
| 660 |
void fr(B* pb, D1* p1, D2* p2) {
|
| 661 |
pb->i = 1; // ill-formed
|
| 662 |
p1->i = 2; // ill-formed
|
| 663 |
p2->i = 3; // OK (access through a D2)
|
| 664 |
+
p2->B::i = 4; // OK (access through a D2, even though naming class is B)
|
|
|
|
| 665 |
int B::* pmi_B = &B::i; // ill-formed
|
| 666 |
int B::* pmi_B2 = &D2::i; // OK (type of &D2::i is int B::*)
|
| 667 |
+
B::j = 5; // ill-formed (not a friend of naming class B)
|
| 668 |
D2::j = 6; // OK (because refers to static member)
|
| 669 |
}
|
| 670 |
|
| 671 |
void D2::mem(B* pb, D1* p1) {
|
| 672 |
pb->i = 1; // ill-formed
|
|
|
|
| 684 |
p1->i = 2; // ill-formed
|
| 685 |
p2->i = 3; // ill-formed
|
| 686 |
}
|
| 687 |
```
|
| 688 |
|
| 689 |
+
— *end example*]
|
| 690 |
+
|
| 691 |
## Access to virtual functions <a id="class.access.virt">[[class.access.virt]]</a>
|
| 692 |
|
| 693 |
The access rules (Clause [[class.access]]) for a virtual function are
|
| 694 |
determined by its declaration and are not affected by the rules for a
|
| 695 |
function that later overrides it.
|
| 696 |
|
| 697 |
+
[*Example 1*:
|
| 698 |
+
|
| 699 |
``` cpp
|
| 700 |
class B {
|
| 701 |
public:
|
| 702 |
virtual int f();
|
| 703 |
};
|
|
|
|
| 710 |
void f() {
|
| 711 |
D d;
|
| 712 |
B* pb = &d;
|
| 713 |
D* pd = &d;
|
| 714 |
|
| 715 |
+
pb->f(); // OK: B::f() is public, D::f() is invoked
|
|
|
|
| 716 |
pd->f(); // error: D::f() is private
|
| 717 |
}
|
| 718 |
```
|
| 719 |
|
| 720 |
+
— *end example*]
|
| 721 |
+
|
| 722 |
Access is checked at the call point using the type of the expression
|
| 723 |
used to denote the object for which the member function is called (`B*`
|
| 724 |
in the example above). The access of the member function in the class in
|
| 725 |
which it was defined (`D` in the example above) is in general not known.
|
| 726 |
|
| 727 |
## Multiple access <a id="class.paths">[[class.paths]]</a>
|
| 728 |
|
| 729 |
If a name can be reached by several paths through a multiple inheritance
|
| 730 |
graph, the access is that of the path that gives most access.
|
| 731 |
|
| 732 |
+
[*Example 1*:
|
| 733 |
+
|
| 734 |
``` cpp
|
| 735 |
class W { public: void f(); };
|
| 736 |
class A : private virtual W { };
|
| 737 |
class B : public virtual W { };
|
| 738 |
class C : public A, public B {
|
|
|
|
| 741 |
```
|
| 742 |
|
| 743 |
Since `W::f()` is available to `C::f()` along the public path through
|
| 744 |
`B`, access is allowed.
|
| 745 |
|
| 746 |
+
— *end example*]
|
| 747 |
+
|
| 748 |
## Nested classes <a id="class.access.nest">[[class.access.nest]]</a>
|
| 749 |
|
| 750 |
A nested class is a member and as such has the same access rights as any
|
| 751 |
other member. The members of an enclosing class have no special access
|
| 752 |
to members of a nested class; the usual access rules (Clause
|
| 753 |
[[class.access]]) shall be obeyed.
|
| 754 |
|
| 755 |
+
[*Example 1*:
|
| 756 |
+
|
| 757 |
``` cpp
|
| 758 |
class E {
|
| 759 |
int x;
|
| 760 |
class B { };
|
| 761 |
|
|
|
|
| 771 |
return p->y; // error: I::y is private
|
| 772 |
}
|
| 773 |
};
|
| 774 |
```
|
| 775 |
|
| 776 |
+
— *end example*]
|
| 777 |
+
|
| 778 |
<!-- Link reference definitions -->
|
| 779 |
+
[basic.compound]: basic.md#basic.compound
|
| 780 |
[basic.def.odr]: basic.md#basic.def.odr
|
| 781 |
[basic.fundamental]: basic.md#basic.fundamental
|
| 782 |
+
[basic.life]: basic.md#basic.life
|
| 783 |
[basic.link]: basic.md#basic.link
|
| 784 |
[basic.lookup]: basic.md#basic.lookup
|
| 785 |
[basic.lookup.elab]: basic.md#basic.lookup.elab
|
| 786 |
[basic.lookup.qual]: basic.md#basic.lookup.qual
|
| 787 |
[basic.lookup.unqual]: basic.md#basic.lookup.unqual
|
| 788 |
[basic.scope]: basic.md#basic.scope
|
| 789 |
[basic.scope.class]: basic.md#basic.scope.class
|
| 790 |
[basic.scope.hiding]: basic.md#basic.scope.hiding
|
| 791 |
+
[basic.start.dynamic]: basic.md#basic.start.dynamic
|
| 792 |
+
[basic.start.static]: basic.md#basic.start.static
|
| 793 |
[basic.start.term]: basic.md#basic.start.term
|
| 794 |
[basic.stc]: basic.md#basic.stc
|
| 795 |
[basic.types]: basic.md#basic.types
|
| 796 |
[c.strings]: strings.md#c.strings
|
| 797 |
[class]: #class
|
|
|
|
| 808 |
[class.ctor]: special.md#class.ctor
|
| 809 |
[class.derived]: #class.derived
|
| 810 |
[class.dtor]: special.md#class.dtor
|
| 811 |
[class.free]: special.md#class.free
|
| 812 |
[class.friend]: #class.friend
|
|
|
|
| 813 |
[class.local]: #class.local
|
| 814 |
[class.mem]: #class.mem
|
| 815 |
[class.member.lookup]: #class.member.lookup
|
| 816 |
[class.mfct]: #class.mfct
|
| 817 |
[class.mfct.non-static]: #class.mfct.non-static
|
|
|
|
| 824 |
[class.static]: #class.static
|
| 825 |
[class.static.data]: #class.static.data
|
| 826 |
[class.static.mfct]: #class.static.mfct
|
| 827 |
[class.this]: #class.this
|
| 828 |
[class.union]: #class.union
|
| 829 |
+
[class.union.anon]: #class.union.anon
|
| 830 |
[class.virtual]: #class.virtual
|
| 831 |
[conv.mem]: conv.md#conv.mem
|
| 832 |
[conv.ptr]: conv.md#conv.ptr
|
| 833 |
[dcl.enum]: dcl.md#dcl.enum
|
| 834 |
[dcl.fct]: dcl.md#dcl.fct
|
|
|
|
| 836 |
[dcl.fct.def.delete]: dcl.md#dcl.fct.def.delete
|
| 837 |
[dcl.fct.default]: dcl.md#dcl.fct.default
|
| 838 |
[dcl.fct.spec]: dcl.md#dcl.fct.spec
|
| 839 |
[dcl.init.aggr]: dcl.md#dcl.init.aggr
|
| 840 |
[dcl.init.ref]: dcl.md#dcl.init.ref
|
| 841 |
+
[dcl.inline]: dcl.md#dcl.inline
|
| 842 |
[dcl.stc]: dcl.md#dcl.stc
|
| 843 |
[dcl.type.cv]: dcl.md#dcl.type.cv
|
| 844 |
[dcl.type.elab]: dcl.md#dcl.type.elab
|
| 845 |
[dcl.typedef]: dcl.md#dcl.typedef
|
| 846 |
+
[depr.static_constexpr]: future.md#depr.static_constexpr
|
| 847 |
+
[expr.ass]: expr.md#expr.ass
|
| 848 |
[expr.call]: expr.md#expr.call
|
| 849 |
[expr.cast]: expr.md#expr.cast
|
| 850 |
[expr.const]: expr.md#expr.const
|
| 851 |
[expr.eq]: expr.md#expr.eq
|
| 852 |
[expr.prim]: expr.md#expr.prim
|
| 853 |
+
[expr.prim.this]: expr.md#expr.prim.this
|
| 854 |
[expr.ref]: expr.md#expr.ref
|
| 855 |
+
[expr.static.cast]: expr.md#expr.static.cast
|
| 856 |
[expr.unary.op]: expr.md#expr.unary.op
|
| 857 |
+
[fig:nonvirt]: #fig:nonvirt
|
| 858 |
+
[fig:virt]: #fig:virt
|
| 859 |
+
[fig:virtnonvirt]: #fig:virtnonvirt
|
| 860 |
[intro.object]: intro.md#intro.object
|
| 861 |
[namespace.def]: dcl.md#namespace.def
|
| 862 |
[namespace.udecl]: dcl.md#namespace.udecl
|
| 863 |
[over]: over.md#over
|
| 864 |
[over.ass]: over.md#over.ass
|
|
|
|
| 868 |
[over.match.funcs]: over.md#over.match.funcs
|
| 869 |
[over.oper]: over.md#over.oper
|
| 870 |
[string.classes]: strings.md#string.classes
|
| 871 |
[temp]: temp.md#temp
|
| 872 |
[temp.arg]: temp.md#temp.arg
|
| 873 |
+
[temp.dep.type]: temp.md#temp.dep.type
|
| 874 |
[temp.friend]: temp.md#temp.friend
|
| 875 |
[temp.inst]: temp.md#temp.inst
|
| 876 |
+
[temp.mem]: temp.md#temp.mem
|
| 877 |
[temp.param]: temp.md#temp.param
|
| 878 |
[temp.spec]: temp.md#temp.spec
|
| 879 |
[temp.variadic]: temp.md#temp.variadic
|
| 880 |
|
| 881 |
[^1]: Base class subobjects are not so constrained.
|