- tmp/tmpwnnlqd4d/{from.md → to.md} +104 -231
tmp/tmpwnnlqd4d/{from.md → to.md}
RENAMED
|
@@ -1,24 +1,24 @@
|
|
| 1 |
-
# Member access control <a id="class.access">[[class.access]]</a>
|
| 2 |
|
| 3 |
A member of a class can be
|
| 4 |
|
| 5 |
-
-
|
| 6 |
-
|
| 7 |
-
-
|
| 8 |
of the class in which it is declared, by classes derived from that
|
| 9 |
class, and by their friends (see [[class.protected]]).
|
| 10 |
-
-
|
| 11 |
restriction.
|
| 12 |
|
| 13 |
A member of a class can also access all the names to which the class has
|
| 14 |
access. A local class of a member function may access the same names
|
| 15 |
-
that the member function itself may access.[^
|
| 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
|
| 20 |
|
| 21 |
[*Example 1*:
|
| 22 |
|
| 23 |
``` cpp
|
| 24 |
class X {
|
|
@@ -33,13 +33,13 @@ struct S {
|
|
| 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
|
| 39 |
-
declarations
|
| 40 |
-
[[namespace.udecl]]
|
| 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*:
|
|
@@ -62,25 +62,26 @@ void f() {
|
|
| 62 |
}
|
| 63 |
```
|
| 64 |
|
| 65 |
— *end note*]
|
| 66 |
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
of a given construct is established without regard to access control. If
|
| 72 |
-
the interpretation established makes use of inaccessible member names or
|
| 73 |
-
base classes, the construct is ill-formed.
|
| 74 |
|
| 75 |
-
|
| 76 |
-
access
|
| 77 |
-
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
constructors, conversion functions, and destructors. — *end note*]
|
| 83 |
|
| 84 |
[*Example 2*:
|
| 85 |
|
| 86 |
``` cpp
|
|
@@ -114,17 +115,17 @@ is as the return type of a member of class `A`. Similarly, the use of
|
|
| 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
|
| 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*
|
| 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 |
|
|
@@ -141,15 +142,19 @@ class D : public U { };
|
|
| 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* (
|
| 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*:
|
|
@@ -183,11 +188,11 @@ public:
|
|
| 183 |
```
|
| 184 |
|
| 185 |
— *end example*]
|
| 186 |
|
| 187 |
[*Note 1*: The effect of access control on the order of allocation of
|
| 188 |
-
data members is
|
| 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 |
|
|
@@ -222,23 +227,23 @@ class C : public B {
|
|
| 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
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
|
| 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`.
|
|
@@ -264,14 +269,15 @@ Here `B` is a public base of `D2`, `D4`, and `D6`, a private base of
|
|
| 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
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
|
|
|
| 273 |
|
| 274 |
``` cpp
|
| 275 |
class B {
|
| 276 |
public:
|
| 277 |
int mi; // non-static member
|
|
@@ -343,12 +349,12 @@ immediate base class of `X`. — *end note*]
|
|
| 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]]
|
| 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 |
|
|
@@ -385,11 +391,11 @@ 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
|
|
@@ -471,26 +477,25 @@ class A {
|
|
| 471 |
};
|
| 472 |
```
|
| 473 |
|
| 474 |
— *end example*]
|
| 475 |
|
| 476 |
-
A
|
| 477 |
-
|
| 478 |
|
| 479 |
``` bnf
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
|
| 483 |
```
|
| 484 |
|
| 485 |
-
[*Note 1*: A
|
| 486 |
-
*template-declaration* (
|
| 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
|
| 492 |
|
| 493 |
[*Example 5*:
|
| 494 |
|
| 495 |
``` cpp
|
| 496 |
class C;
|
|
@@ -515,16 +520,17 @@ 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]]
|
| 521 |
-
|
|
|
|
| 522 |
|
| 523 |
-
When a
|
| 524 |
-
|
| 525 |
-
|
| 526 |
|
| 527 |
[*Example 6*:
|
| 528 |
|
| 529 |
``` cpp
|
| 530 |
class Y {
|
|
@@ -535,12 +541,12 @@ class Y {
|
|
| 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
|
| 541 |
-
|
| 542 |
|
| 543 |
[*Example 7*:
|
| 544 |
|
| 545 |
``` cpp
|
| 546 |
class M {
|
|
@@ -549,23 +555,23 @@ class M {
|
|
| 549 |
};
|
| 550 |
```
|
| 551 |
|
| 552 |
— *end example*]
|
| 553 |
|
| 554 |
-
Such a function is implicitly an inline
|
| 555 |
-
|
| 556 |
-
class in which it is defined. A friend
|
| 557 |
-
class is not
|
| 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
|
| 563 |
scope of the class containing the friend declaration. The meaning of the
|
| 564 |
friend declaration is the same whether the friend declaration appears in
|
| 565 |
-
the
|
| 566 |
-
|
| 567 |
|
| 568 |
Friendship is neither inherited nor transitive.
|
| 569 |
|
| 570 |
[*Example 8*:
|
| 571 |
|
|
@@ -592,13 +598,13 @@ class D : public B {
|
|
| 592 |
};
|
| 593 |
```
|
| 594 |
|
| 595 |
— *end example*]
|
| 596 |
|
| 597 |
-
If a friend declaration appears in a local class
|
| 598 |
-
|
| 599 |
-
|
| 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
|
|
@@ -619,27 +625,27 @@ void f() {
|
|
| 619 |
friend void a(); // error, ::a is not considered
|
| 620 |
friend void b(); // OK
|
| 621 |
friend void c(); // error
|
| 622 |
};
|
| 623 |
X* px; // OK, but ::X is found
|
| 624 |
-
Z* pz; // error
|
| 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
|
| 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
|
| 635 |
-
[[class.access.base]]
|
| 636 |
member is granted because the reference occurs in a friend or member of
|
| 637 |
-
some class `C`. If the access is to form a pointer to member
|
| 638 |
-
[[expr.unary.op]]
|
| 639 |
class derived from `C`. All other accesses involve a (possibly implicit)
|
| 640 |
-
object expression
|
| 641 |
expression shall be `C` or a class derived from `C`.
|
| 642 |
|
| 643 |
[*Example 1*:
|
| 644 |
|
| 645 |
``` cpp
|
|
@@ -656,45 +662,45 @@ class D2 : public B {
|
|
| 656 |
friend void fr(B*,D1*,D2*);
|
| 657 |
void mem(B*,D1*);
|
| 658 |
};
|
| 659 |
|
| 660 |
void fr(B* pb, D1* p1, D2* p2) {
|
| 661 |
-
pb->i = 1; //
|
| 662 |
-
p1->i = 2; //
|
| 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; //
|
| 666 |
int B::* pmi_B2 = &D2::i; // OK (type of &D2::i is int B::*)
|
| 667 |
-
B::j = 5; //
|
| 668 |
D2::j = 6; // OK (because refers to static member)
|
| 669 |
}
|
| 670 |
|
| 671 |
void D2::mem(B* pb, D1* p1) {
|
| 672 |
-
pb->i = 1; //
|
| 673 |
-
p1->i = 2; //
|
| 674 |
i = 3; // OK (access through this)
|
| 675 |
B::i = 4; // OK (access through this, qualification ignored)
|
| 676 |
-
int B::* pmi_B = &B::i; //
|
| 677 |
int B::* pmi_B2 = &D2::i; // OK
|
| 678 |
j = 5; // OK (because j refers to static member)
|
| 679 |
B::j = 6; // OK (because B::j refers to static member)
|
| 680 |
}
|
| 681 |
|
| 682 |
void g(B* pb, D1* p1, D2* p2) {
|
| 683 |
-
pb->i = 1; //
|
| 684 |
-
p1->i = 2; //
|
| 685 |
-
p2->i = 3; //
|
| 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
|
| 694 |
-
|
| 695 |
-
|
| 696 |
|
| 697 |
[*Example 1*:
|
| 698 |
|
| 699 |
``` cpp
|
| 700 |
class B {
|
|
@@ -722,11 +728,11 @@ void f() {
|
|
| 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*:
|
|
@@ -743,16 +749,16 @@ class C : public A, public B {
|
|
| 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
|
| 753 |
-
|
| 754 |
|
| 755 |
[*Example 1*:
|
| 756 |
|
| 757 |
``` cpp
|
| 758 |
class E {
|
|
@@ -773,138 +779,5 @@ class E {
|
|
| 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
|
| 798 |
-
[class.abstract]: #class.abstract
|
| 799 |
-
[class.access]: #class.access
|
| 800 |
-
[class.access.base]: #class.access.base
|
| 801 |
-
[class.access.nest]: #class.access.nest
|
| 802 |
-
[class.access.spec]: #class.access.spec
|
| 803 |
-
[class.access.virt]: #class.access.virt
|
| 804 |
-
[class.base.init]: special.md#class.base.init
|
| 805 |
-
[class.bit]: #class.bit
|
| 806 |
-
[class.cdtor]: special.md#class.cdtor
|
| 807 |
-
[class.copy]: special.md#class.copy
|
| 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
|
| 818 |
-
[class.mi]: #class.mi
|
| 819 |
-
[class.name]: #class.name
|
| 820 |
-
[class.nest]: #class.nest
|
| 821 |
-
[class.nested.type]: #class.nested.type
|
| 822 |
-
[class.paths]: #class.paths
|
| 823 |
-
[class.protected]: #class.protected
|
| 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
|
| 835 |
-
[dcl.fct.def]: dcl.md#dcl.fct.def
|
| 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
|
| 865 |
-
[over.load]: over.md#over.load
|
| 866 |
-
[over.match]: over.md#over.match
|
| 867 |
-
[over.match.call]: over.md#over.match.call
|
| 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.
|
| 882 |
-
|
| 883 |
-
[^2]: This ensures that two subobjects that have the same class type and
|
| 884 |
-
that belong to the same most derived object are not allocated at the
|
| 885 |
-
same address ([[expr.eq]]).
|
| 886 |
-
|
| 887 |
-
[^3]: The acronym POD stands for “plain old data”.
|
| 888 |
-
|
| 889 |
-
[^4]: See, for example, `<cstring>` ([[c.strings]]).
|
| 890 |
-
|
| 891 |
-
[^5]: A function with the same name but a different parameter list
|
| 892 |
-
(Clause [[over]]) as a virtual function is not necessarily virtual
|
| 893 |
-
and does not override. The use of the `virtual` specifier in the
|
| 894 |
-
declaration of an overriding function is legal but redundant (has
|
| 895 |
-
empty semantics). Access control (Clause [[class.access]]) is not
|
| 896 |
-
considered in determining overriding.
|
| 897 |
-
|
| 898 |
-
[^6]: Multi-level pointers to classes or references to multi-level
|
| 899 |
-
pointers to classes are not allowed.
|
| 900 |
-
|
| 901 |
-
[^7]: Access permissions are thus transitive and cumulative to nested
|
| 902 |
-
and local classes.
|
| 903 |
-
|
| 904 |
-
[^8]: As specified previously in Clause [[class.access]], private
|
| 905 |
-
members of a base class remain inaccessible even to derived classes
|
| 906 |
-
unless `friend` declarations within the base class definition are
|
| 907 |
-
used to grant access explicitly.
|
| 908 |
-
|
| 909 |
-
[^9]: This additional check does not apply to other members, e.g.,
|
| 910 |
-
static data members or enumerator member constants.
|
|
|
|
| 1 |
+
## Member access control <a id="class.access">[[class.access]]</a>
|
| 2 |
|
| 3 |
A member of a class can be
|
| 4 |
|
| 5 |
+
- private; that is, its name can be used only by members and friends of
|
| 6 |
+
the class in which it is declared.
|
| 7 |
+
- protected; that is, its name can be used only by members and friends
|
| 8 |
of the class in which it is declared, by classes derived from that
|
| 9 |
class, and by their friends (see [[class.protected]]).
|
| 10 |
+
- public; that is, its name can be used anywhere without access
|
| 11 |
restriction.
|
| 12 |
|
| 13 |
A member of a class can also access all the names to which the class has
|
| 14 |
access. A local class of a member function may access the same names
|
| 15 |
+
that the member function itself may access.[^11]
|
| 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 {
|
|
|
|
| 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*:
|
|
|
|
| 62 |
}
|
| 63 |
```
|
| 64 |
|
| 65 |
— *end note*]
|
| 66 |
|
| 67 |
+
[*Note 3*: Access to members and base classes is controlled, not their
|
| 68 |
+
visibility [[basic.scope.hiding]]. Names of members are still visible,
|
| 69 |
+
and implicit conversions to base classes are still considered, when
|
| 70 |
+
those members and base classes are inaccessible. — *end note*]
|
|
|
|
|
|
|
|
|
|
| 71 |
|
| 72 |
+
The interpretation of a given construct is established without regard to
|
| 73 |
+
access control. If the interpretation established makes use of
|
| 74 |
+
inaccessible member names or base classes, the construct is ill-formed.
|
|
|
|
|
|
|
| 75 |
|
| 76 |
+
All access controls in [[class.access]] affect the ability to access a
|
| 77 |
+
class member name from the declaration of a particular entity, including
|
| 78 |
+
parts of the declaration preceding the name of the entity being declared
|
| 79 |
+
and, if the entity is a class, the definitions of members of the class
|
| 80 |
+
appearing outside the class’s *member-specification*.
|
| 81 |
+
|
| 82 |
+
[*Note 4*: This access also applies to implicit references to
|
| 83 |
constructors, conversion functions, and destructors. — *end note*]
|
| 84 |
|
| 85 |
[*Example 2*:
|
| 86 |
|
| 87 |
``` cpp
|
|
|
|
| 115 |
`A`, so checking of *base-specifier*s must be deferred until the entire
|
| 116 |
*base-specifier-list* has been seen.
|
| 117 |
|
| 118 |
— *end example*]
|
| 119 |
|
| 120 |
+
The names in a default argument [[dcl.fct.default]] are bound at the
|
| 121 |
point of declaration, and access is checked at that point rather than at
|
| 122 |
any points of use of the default argument. Access checking for default
|
| 123 |
arguments in function templates and in member functions of class
|
| 124 |
templates is performed as described in [[temp.inst]].
|
| 125 |
|
| 126 |
+
The names in a default *template-argument* [[temp.param]] have their
|
| 127 |
access checked in the context in which they appear rather than at any
|
| 128 |
points of use of the default *template-argument*.
|
| 129 |
|
| 130 |
[*Example 3*:
|
| 131 |
|
|
|
|
| 142 |
D <C<B> >* d; // access error, C::TT is protected
|
| 143 |
```
|
| 144 |
|
| 145 |
— *end example*]
|
| 146 |
|
| 147 |
+
### Access specifiers <a id="class.access.spec">[[class.access.spec]]</a>
|
| 148 |
|
| 149 |
+
Member declarations can be labeled by an *access-specifier* (
|
| 150 |
[[class.derived]]):
|
| 151 |
|
| 152 |
+
``` bnf
|
| 153 |
+
access-specifier ':' member-specificationₒₚₜ
|
| 154 |
+
```
|
| 155 |
+
|
| 156 |
An *access-specifier* specifies the access rules for members following
|
| 157 |
it until the end of the class or until another *access-specifier* is
|
| 158 |
encountered.
|
| 159 |
|
| 160 |
[*Example 1*:
|
|
|
|
| 188 |
```
|
| 189 |
|
| 190 |
— *end example*]
|
| 191 |
|
| 192 |
[*Note 1*: The effect of access control on the order of allocation of
|
| 193 |
+
data members is specified in [[expr.rel]]. — *end note*]
|
| 194 |
|
| 195 |
When a member is redeclared within its class definition, the access
|
| 196 |
specified at its redeclaration shall be the same as at its initial
|
| 197 |
declaration.
|
| 198 |
|
|
|
|
| 227 |
};
|
| 228 |
```
|
| 229 |
|
| 230 |
— *end example*]
|
| 231 |
|
| 232 |
+
### Accessibility of base classes and base class members <a id="class.access.base">[[class.access.base]]</a>
|
| 233 |
|
| 234 |
+
If a class is declared to be a base class [[class.derived]] for another
|
| 235 |
+
class using the `public` access specifier, the public members of the
|
| 236 |
+
base class are accessible as public members of the derived class and
|
| 237 |
+
protected members of the base class are accessible as protected members
|
| 238 |
+
of the derived class. If a class is declared to be a base class for
|
| 239 |
+
another class using the `protected` access specifier, the public and
|
| 240 |
+
protected members of the base class are accessible as protected members
|
| 241 |
+
of the derived class. If a class is declared to be a base class for
|
| 242 |
+
another class using the `private` access specifier, the public and
|
| 243 |
+
protected members of the base class are accessible as private members of
|
| 244 |
+
the derived class.[^12]
|
| 245 |
|
| 246 |
In the absence of an *access-specifier* for a base class, `public` is
|
| 247 |
assumed when the derived class is defined with the *class-key* `struct`
|
| 248 |
and `private` is assumed when the class is defined with the *class-key*
|
| 249 |
`class`.
|
|
|
|
| 269 |
|
| 270 |
[*Note 1*:
|
| 271 |
|
| 272 |
A member of a private base class might be inaccessible as an inherited
|
| 273 |
member name, but accessible directly. Because of the rules on pointer
|
| 274 |
+
conversions [[conv.ptr]] and explicit casts ([[expr.type.conv]],
|
| 275 |
+
[[expr.static.cast]], [[expr.cast]]), a conversion from a pointer to a
|
| 276 |
+
derived class to a pointer to an inaccessible base class might be
|
| 277 |
+
ill-formed if an implicit conversion is used, but well-formed if an
|
| 278 |
+
explicit cast is used. For example,
|
| 279 |
|
| 280 |
``` cpp
|
| 281 |
class B {
|
| 282 |
public:
|
| 283 |
int mi; // non-static member
|
|
|
|
| 349 |
The access to a member is affected by the class in which the member is
|
| 350 |
named. This naming class is the class in which the member name was
|
| 351 |
looked up and found.
|
| 352 |
|
| 353 |
[*Note 3*: This class can be explicit, e.g., when a *qualified-id* is
|
| 354 |
+
used, or implicit, e.g., when a class member access operator
|
| 355 |
+
[[expr.ref]] is used (including cases where an implicit “`this->`” is
|
| 356 |
added). If both a class member access operator and a *qualified-id* are
|
| 357 |
used to name the member (as in `p->T::m`), the class naming the member
|
| 358 |
is the class denoted by the *nested-name-specifier* of the
|
| 359 |
*qualified-id* (that is, `T`). — *end note*]
|
| 360 |
|
|
|
|
| 391 |
to the naming class of the right operand.
|
| 392 |
|
| 393 |
[*Note 4*: This requirement is in addition to the requirement that the
|
| 394 |
member be accessible as named. — *end note*]
|
| 395 |
|
| 396 |
+
### Friends <a id="class.friend">[[class.friend]]</a>
|
| 397 |
|
| 398 |
A friend of a class is a function or class that is given permission to
|
| 399 |
use the private and protected member names from the class. A class
|
| 400 |
specifies its friends, if any, by way of friend declarations. Such
|
| 401 |
declarations give special access rights to the friends, but they do not
|
|
|
|
| 477 |
};
|
| 478 |
```
|
| 479 |
|
| 480 |
— *end example*]
|
| 481 |
|
| 482 |
+
A friend declaration that does not declare a function shall have one of
|
| 483 |
+
the following forms:
|
| 484 |
|
| 485 |
``` bnf
|
| 486 |
+
friend elaborated-type-specifier ';'
|
| 487 |
+
friend simple-type-specifier ';'
|
| 488 |
+
friend typename-specifier ';'
|
| 489 |
```
|
| 490 |
|
| 491 |
+
[*Note 1*: A friend declaration may be the *declaration* in a
|
| 492 |
+
*template-declaration* ([[temp.pre]], [[temp.friend]]). — *end note*]
|
|
|
|
| 493 |
|
| 494 |
If the type specifier in a `friend` declaration designates a (possibly
|
| 495 |
cv-qualified) class type, that class is declared as a friend; otherwise,
|
| 496 |
+
the friend declaration is ignored.
|
| 497 |
|
| 498 |
[*Example 5*:
|
| 499 |
|
| 500 |
``` cpp
|
| 501 |
class C;
|
|
|
|
| 520 |
```
|
| 521 |
|
| 522 |
— *end example*]
|
| 523 |
|
| 524 |
A function first declared in a friend declaration has the linkage of the
|
| 525 |
+
namespace of which it is a member ([[basic.link]],
|
| 526 |
+
[[namespace.memdef]]). Otherwise, the function retains its previous
|
| 527 |
+
linkage [[dcl.stc]].
|
| 528 |
|
| 529 |
+
When a friend declaration refers to an overloaded name or operator, only
|
| 530 |
+
the function specified by the parameter types becomes a friend. A member
|
| 531 |
+
function of a class `X` can be a friend of a class `Y`.
|
| 532 |
|
| 533 |
[*Example 6*:
|
| 534 |
|
| 535 |
``` cpp
|
| 536 |
class Y {
|
|
|
|
| 541 |
```
|
| 542 |
|
| 543 |
— *end example*]
|
| 544 |
|
| 545 |
A function can be defined in a friend declaration of a class if and only
|
| 546 |
+
if the class is a non-local class [[class.local]], the function name is
|
| 547 |
+
unqualified, and the function has namespace scope.
|
| 548 |
|
| 549 |
[*Example 7*:
|
| 550 |
|
| 551 |
``` cpp
|
| 552 |
class M {
|
|
|
|
| 555 |
};
|
| 556 |
```
|
| 557 |
|
| 558 |
— *end example*]
|
| 559 |
|
| 560 |
+
Such a function is implicitly an inline [[dcl.inline]] function if it is
|
| 561 |
+
attached to the global module. A friend function defined in a class is
|
| 562 |
+
in the (lexical) scope of the class in which it is defined. A friend
|
| 563 |
+
function defined outside the class is not [[basic.lookup.unqual]].
|
| 564 |
|
| 565 |
No *storage-class-specifier* shall appear in the *decl-specifier-seq* of
|
| 566 |
a friend declaration.
|
| 567 |
|
| 568 |
A name nominated by a friend declaration shall be accessible in the
|
| 569 |
scope of the class containing the friend declaration. The meaning of the
|
| 570 |
friend declaration is the same whether the friend declaration appears in
|
| 571 |
+
the private, protected, or public [[class.mem]] portion of the class
|
| 572 |
+
*member-specification*.
|
| 573 |
|
| 574 |
Friendship is neither inherited nor transitive.
|
| 575 |
|
| 576 |
[*Example 8*:
|
| 577 |
|
|
|
|
| 598 |
};
|
| 599 |
```
|
| 600 |
|
| 601 |
— *end example*]
|
| 602 |
|
| 603 |
+
If a friend declaration appears in a local class [[class.local]] and the
|
| 604 |
+
name specified is an unqualified name, a prior declaration is looked up
|
| 605 |
+
without considering scopes that are outside the innermost enclosing
|
| 606 |
non-class scope. For a friend function declaration, if there is no prior
|
| 607 |
declaration, the program is ill-formed. For a friend class declaration,
|
| 608 |
if there is no prior declaration, the class that is specified belongs to
|
| 609 |
the innermost enclosing non-class scope, but if it is subsequently
|
| 610 |
referenced, its name is not found by name lookup until a matching
|
|
|
|
| 625 |
friend void a(); // error, ::a is not considered
|
| 626 |
friend void b(); // OK
|
| 627 |
friend void c(); // error
|
| 628 |
};
|
| 629 |
X* px; // OK, but ::X is found
|
| 630 |
+
Z* pz; // error: no Z is found
|
| 631 |
}
|
| 632 |
```
|
| 633 |
|
| 634 |
— *end example*]
|
| 635 |
|
| 636 |
+
### Protected member access <a id="class.protected">[[class.protected]]</a>
|
| 637 |
|
| 638 |
+
An additional access check beyond those described earlier in
|
| 639 |
[[class.access]] is applied when a non-static data member or non-static
|
| 640 |
+
member function is a protected member of its naming class
|
| 641 |
+
[[class.access.base]].[^13] As described earlier, access to a protected
|
| 642 |
member is granted because the reference occurs in a friend or member of
|
| 643 |
+
some class `C`. If the access is to form a pointer to member
|
| 644 |
+
[[expr.unary.op]], the *nested-name-specifier* shall denote `C` or a
|
| 645 |
class derived from `C`. All other accesses involve a (possibly implicit)
|
| 646 |
+
object expression [[expr.ref]]. In this case, the class of the object
|
| 647 |
expression shall be `C` or a class derived from `C`.
|
| 648 |
|
| 649 |
[*Example 1*:
|
| 650 |
|
| 651 |
``` cpp
|
|
|
|
| 662 |
friend void fr(B*,D1*,D2*);
|
| 663 |
void mem(B*,D1*);
|
| 664 |
};
|
| 665 |
|
| 666 |
void fr(B* pb, D1* p1, D2* p2) {
|
| 667 |
+
pb->i = 1; // error
|
| 668 |
+
p1->i = 2; // error
|
| 669 |
p2->i = 3; // OK (access through a D2)
|
| 670 |
p2->B::i = 4; // OK (access through a D2, even though naming class is B)
|
| 671 |
+
int B::* pmi_B = &B::i; // error
|
| 672 |
int B::* pmi_B2 = &D2::i; // OK (type of &D2::i is int B::*)
|
| 673 |
+
B::j = 5; // error: not a friend of naming class B
|
| 674 |
D2::j = 6; // OK (because refers to static member)
|
| 675 |
}
|
| 676 |
|
| 677 |
void D2::mem(B* pb, D1* p1) {
|
| 678 |
+
pb->i = 1; // error
|
| 679 |
+
p1->i = 2; // error
|
| 680 |
i = 3; // OK (access through this)
|
| 681 |
B::i = 4; // OK (access through this, qualification ignored)
|
| 682 |
+
int B::* pmi_B = &B::i; // error
|
| 683 |
int B::* pmi_B2 = &D2::i; // OK
|
| 684 |
j = 5; // OK (because j refers to static member)
|
| 685 |
B::j = 6; // OK (because B::j refers to static member)
|
| 686 |
}
|
| 687 |
|
| 688 |
void g(B* pb, D1* p1, D2* p2) {
|
| 689 |
+
pb->i = 1; // error
|
| 690 |
+
p1->i = 2; // error
|
| 691 |
+
p2->i = 3; // error
|
| 692 |
}
|
| 693 |
```
|
| 694 |
|
| 695 |
— *end example*]
|
| 696 |
|
| 697 |
+
### Access to virtual functions <a id="class.access.virt">[[class.access.virt]]</a>
|
| 698 |
|
| 699 |
+
The access rules [[class.access]] for a virtual function are determined
|
| 700 |
+
by its declaration and are not affected by the rules for a function that
|
| 701 |
+
later overrides it.
|
| 702 |
|
| 703 |
[*Example 1*:
|
| 704 |
|
| 705 |
``` cpp
|
| 706 |
class B {
|
|
|
|
| 728 |
Access is checked at the call point using the type of the expression
|
| 729 |
used to denote the object for which the member function is called (`B*`
|
| 730 |
in the example above). The access of the member function in the class in
|
| 731 |
which it was defined (`D` in the example above) is in general not known.
|
| 732 |
|
| 733 |
+
### Multiple access <a id="class.paths">[[class.paths]]</a>
|
| 734 |
|
| 735 |
If a name can be reached by several paths through a multiple inheritance
|
| 736 |
graph, the access is that of the path that gives most access.
|
| 737 |
|
| 738 |
[*Example 1*:
|
|
|
|
| 749 |
Since `W::f()` is available to `C::f()` along the public path through
|
| 750 |
`B`, access is allowed.
|
| 751 |
|
| 752 |
— *end example*]
|
| 753 |
|
| 754 |
+
### Nested classes <a id="class.access.nest">[[class.access.nest]]</a>
|
| 755 |
|
| 756 |
A nested class is a member and as such has the same access rights as any
|
| 757 |
other member. The members of an enclosing class have no special access
|
| 758 |
+
to members of a nested class; the usual access rules [[class.access]]
|
| 759 |
+
shall be obeyed.
|
| 760 |
|
| 761 |
[*Example 1*:
|
| 762 |
|
| 763 |
``` cpp
|
| 764 |
class E {
|
|
|
|
| 779 |
};
|
| 780 |
```
|
| 781 |
|
| 782 |
— *end example*]
|
| 783 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|