40 lines
2.6 KiB
Markdown
40 lines
2.6 KiB
Markdown
[class.protected]
|
||
|
||
# 11 Classes [[class]](./#class)
|
||
|
||
## 11.8 Member access control [[class.access]](class.access#class.protected)
|
||
|
||
### 11.8.5 Protected member access [class.protected]
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L5181)
|
||
|
||
An additional access check beyond those described earlier in [[class.access]](class.access "11.8 Member access control") is applied when a non-static data member or non-static member function is a
|
||
protected member of its naming class ([[class.access.base]](class.access.base "11.8.3 Accessibility of base classes and base class members"))[.](#1.sentence-1)[98](#footnote-98 "This additional check does not apply to other members, e.g., static data members or enumerator member constants.")
|
||
|
||
As described earlier, access to a protected member is granted because the
|
||
reference occurs in a friend or direct member of some class C[.](#1.sentence-2)
|
||
|
||
If the access is
|
||
to form a pointer to member ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")), the[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") shall denote C or a class derived fromC[.](#1.sentence-3)
|
||
|
||
All other accesses involve a (possibly implicit) object
|
||
expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access"))[.](#1.sentence-4)
|
||
|
||
In this case, the class of the object expression shall beC or a class derived from C[.](#1.sentence-5)
|
||
|
||
[*Example [1](#example-1)*: class B {protected:int i; static int j;};
|
||
|
||
class D1 : public B {};
|
||
|
||
class D2 : public B {friend void fr(B*,D1*,D2*); void mem(B*,D1*);};
|
||
|
||
void fr(B* pb, D1* p1, D2* p2) { pb->i = 1; // error p1->i = 2; // error p2->i = 3; // OK (access through a D2) p2->B::i = 4; // OK (access through a D2, even though naming class is B)int B::* pmi_B = &B::i; // errorint B::* pmi_B2 = &D2::i; // OK (type of &D2::i is int B::*) B::j = 5; // error: not a friend of naming class B D2::j = 6; // OK (because refers to static member)}void D2::mem(B* pb, D1* p1) { pb->i = 1; // error p1->i = 2; // error i = 3; // OK (access through this) B::i = 4; // OK (access through this, qualification ignored)int B::* pmi_B = &B::i; // errorint B::* pmi_B2 = &D2::i; // OK j = 5; // OK (because j refers to static member) B::j = 6; // OK (because B::j refers to static member)}void g(B* pb, D1* p1, D2* p2) { pb->i = 1; // error p1->i = 2; // error p2->i = 3; // error} â *end example*]
|
||
|
||
[98)](#footnote-98)[98)](#footnoteref-98)
|
||
|
||
This
|
||
additional check does not apply to other members,
|
||
e.g., static data members or enumerator member constants[.](#footnote-98.sentence-1)
|