[class.access.base] (original) (raw)

11 Classes [class]

11.8 Member access control [class.access]

11.8.3 Accessibility of base classes and base class members [class.access.base]

If a class is declared to be a base class ([class.derived]) for another class using thepublicaccess specifier, the public members of the base class are accessible as public members of the derived class and protected members of the base class are accessible as protected members of the derived class.

If a class is declared to be a base class for another class using theprotectedaccess specifier, the public and protected members of the base class are accessible as protected members of the derived class.

If a class is declared to be a base class for another class using theprivateaccess specifier, the public and protected members of the base class are accessible as private members of the derived class.98

In the absence of anaccess-specifierfor a base class,publicis assumed when the derived class is defined with the class-key structandprivateis assumed when the class is defined with the class-key class.

[Example 1: class B { };class D1 : private B { };class D2 : public B { };class D3 : B { }; struct D4 : public B { };struct D5 : private B { };struct D6 : B { }; class D7 : protected B { };struct D8 : protected B { };

HereBis a public base ofD2,D4, andD6, a private base ofD1,D3, andD5, and a protected base ofD7andD8.

— _end example_]

[Note 1:

A member of a private base class can be inaccessible as inherited, but accessible directly.

Because of the rules on pointer conversions ([conv.ptr]) and explicit casts ([expr.type.conv], [expr.static.cast], [expr.cast]), a conversion from a pointer to a derived class to a pointer to an inaccessible base class can be ill-formed if an implicit conversion is used, but well-formed if an explicit cast is used.

[Example 2: class B { public: int mi; static int si; };class D : private B { };class DD : public D { void f();};void DD::f() { mi = 3; si = 3; ::B b; b.mi = 3; b.si = 3; ::B::si = 3; ::B* bp1 = this; ::B* bp2 = (::B*)this; bp2->mi = 3; } — _end example_]

— _end note_]

A base classBofNisaccessibleat_R_, if

[Example 3: class B { public: int m;};class S: private B { friend class N;};class N: private S { void f() { B* p = this; } }; — _end example_]

If a base class is accessible, one can implicitly convert a pointer to a derived class to a pointer to that base class ([conv.ptr], [conv.mem]).

[Note 2:

It follows that members and friends of a classXcan implicitly convert anX*to a pointer to a private or protected immediate base class ofX.

— _end note_]

The access to a member is affected by the class in which the member is named.

This naming class is the class in whose scope name lookup performed a search that found the member.

[Note 3:

This class can be explicit, e.g., when aqualified-idis used, or implicit, e.g., when a class member access operator ([expr.ref]) is used (including cases where an implicit “this->” is added).

If both a class member access operator and aqualified-idare used to name the member (as inp->T​::​m), the class naming the member is the class denoted by thenested-name-specifierof thequalified-id(that is,T).

— _end note_]

A membermis accessible at the point_R_when named in classNif

If a class member access operator, including an implicit “this->”, is used to access a non-static data member or non-static member function, the reference is ill-formed if the left operand (considered as a pointer in the “.” operator case) cannot be implicitly converted to a pointer to the naming class of the right operand.

[Note 4:

This requirement is in addition to the requirement that the member be accessible as named.

— _end note_]