[class.access.base]

# 11 Classes [[class]](./#class)

## 11.8 Member access control [[class.access]](class.access#base)

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

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4607)

If a class is declared to be a base class ([[class.derived]](class.derived "11.7 Derived classes")) for another class using thepublic access 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[.](#1.sentence-1)

If a class is declared to be a base class for another class using theprotected access specifier, the
public and protected members of the base class are accessible as
protected members of the derived class[.](#1.sentence-2)

If a class is declared to be a base class for another class using theprivate access specifier, the
public and protected
members of the base class are accessible as private
members of the derived class[.](#1.sentence-3)[97](#footnote-97 "As specified previously in [class.access], private members of a base class remain inaccessible even to derived classes unless friend declarations within the base class definition are used to grant access explicitly.")

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4633)

In the absence of an[*access-specifier*](class.derived.general#nt:access-specifier "11.7.1 General [class.derived.general]") for a base class,public is assumed when the derived class is
defined with the [*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]")struct andprivate is assumed when the class is
defined with the [*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]")class[.](#2.sentence-1)

[*Example [1](#example-1)*: class B { /* ... */ };class D1 : private B { /* ... */ };class D2 : public B { /* ... */ };class D3 : B { /* ... */ }; // B private by defaultstruct D4 : public B { /* ... */ };struct D5 : private B { /* ... */ };struct D6 : B { /* ... */ }; // B public by defaultclass D7 : protected B { /* ... */ };struct D8 : protected B { /* ... */ };

HereB is a public base ofD2,D4,
andD6,
a private base ofD1,D3,
andD5,
and a protected base ofD7 andD8[.](#2.sentence-2)

â *end example*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4677)

[*Note [1](#note-1)*:

A member of a private base class can be inaccessible as inherited,
but accessible directly[.](#3.sentence-1)

Because of the rules on pointer conversions ([[conv.ptr]](conv.ptr "7.3.12 Pointer conversions")) and
explicit casts ([[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)")),
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[.](#3.sentence-2)

[*Example [2](#example-2)*: class B {public:int mi; // non-static memberstatic int si; // static member};class D : private B {};class DD : public D {void f();};

void DD::f() { mi = 3; // error: mi is private in D si = 3; // error: si is private in D::B b;
 b.mi = 3; // OK (b.mi is different from this->mi) b.si = 3; // OK (b.si is different from this->si)::B::si = 3; // OK::B* bp1 = this; // error: B is a private base class::B* bp2 = (::B*)this; // OK with cast bp2->mi = 3; // OK, access through a pointer to B.} â *end example*]

â *end note*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4714)

A base classB ofN is[*accessible*](#def:accessible "11.8.3 Accessibility of base classes and base class members [class.access.base]") at*R*,
if

- [(4.1)](#4.1)

an invented public member ofB would be a public member ofN, or

- [(4.2)](#4.2)

*R* occurs in a direct member or friend of classN,
and an invented public member ofB would be a private or protected member ofN, or

- [(4.3)](#4.3)

*R* occurs in a direct member or friend of a classP derived fromN,
and an invented public member ofB would be a private or protected member ofP, or

- [(4.4)](#4.4)

there exists a classS such thatB is a base class ofS accessible at*R* andS is a base class ofN accessible at*R*[.](#4.sentence-1)

[*Example [3](#example-3)*: class B {public:int m;};

class S: private B {friend class N;};

class N: private S {void f() { B* p = this; // OK because class S satisfies the fourth condition above: B is a base class of N// accessible in f() because B is an accessible base class of S and S is an accessible// base class of N.}}; â *end example*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4786)

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.ptr "7.3.12 Pointer conversions"), [[conv.mem]](conv.mem "7.3.13 Pointer-to-member conversions"))[.](#5.sentence-1)

[*Note [2](#note-2)*:

It follows that
members and friends of a classX can implicitly convert anX* to a pointer to a private or protected immediate base class ofX[.](#5.sentence-2)

â *end note*]

An expression E that designates a member m has a [*designating class*](#def:class,designating "11.8.3 Accessibility of base classes and base class members [class.access.base]") that affects the access to m[.](#5.sentence-3)

This designating class is either

- [(5.1)](#5.1)

the innermost class of which m is directly a member
if E is a [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") or

- [(5.2)](#5.2)

the class in whose scope name lookup performed a search
that found m otherwise[.](#5.sentence-4)

[*Note [3](#note-3)*:

This class can be explicit, e.g., when a[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") is used, or implicit, e.g., when a class member access operator ([[expr.ref]](expr.ref "7.6.1.5 Class member access")) is used (including cases where an implicit
âthis->â
is
added)[.](#5.sentence-5)

If both a class member access operator and a[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") are used to name the member (as inp->T​::​m),
the class designating the member is the class designated by the[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of the[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") (that is,T)[.](#5.sentence-6)

â *end note*]

A memberm is accessible at the point*R* when designated in classN if

- [(5.3)](#5.3)

m is designated by a [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]"), or

- [(5.4)](#5.4)

m as a member ofN is public, or

- [(5.5)](#5.5)

m as a member ofN is private, and*R* occurs in a direct member or friend of classN,
or

- [(5.6)](#5.6)

m as a member ofN is protected, and*R* occurs in a direct member or friend of classN,
or in a member of a classP derived fromN,
wherem as a member ofP is public, private, or protected, or

- [(5.7)](#5.7)

there exists a base classB ofN that is accessible at*R*,
andm is accessible at*R* when designated in classB[.](#5.sentence-7)
  [*Example [4](#example-4)*: class B;class A {private:int i; friend void f(B*);};class B : public A { };void f(B* p) { p->i = 1; // OK, B* can be implicitly converted to A*, and f has access to i in A} â *end example*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L4898)

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 designating class of the right operand[.](#6.sentence-1)

[*Note [4](#note-4)*:

This requirement is in addition to the requirement that
the member be accessible as designated[.](#6.sentence-2)

â *end note*]

[97)](#footnote-97)[97)](#footnoteref-97)

As specified previously in [[class.access]](class.access "11.8 Member access control"),
private members of a base class remain inaccessible even to derived classes
unless friend
declarations within the base class definition are used to grant access explicitly[.](#footnote-97.sentence-1)
