14 Member access control [class.access]

14.1 Access specifiers [class.access.spec]

Member declarations can be labeled by an access-specifier ([class.derived]):
access-specifier : member-specification
An access-specifier specifies the access rules for members following it until the end of the class or until another access-specifier is encountered.
[Example
:
class X {
  int a;            // X​::​a is private by default: class used
public:
  int b;            // X​::​b is public
  int c;            // X​::​c is public
};
end example
]
Any number of access specifiers is allowed and no particular order is required.
[Example
:
struct S {
  int a;            // S​::​a is public by default: struct used
protected:
  int b;            // S​::​b is protected
private:
  int c;            // S​::​c is private
public:
  int d;            // S​::​d is public
};
end example
]
[Note
:
The effect of access control on the order of allocation of data members is described in [class.mem].
end note
]
When a member is redeclared within its class definition, the access specified at its redeclaration shall be the same as at its initial declaration.
[Example
:
struct S {
  class A;
  enum E : int;
private:
  class A { };        // error: cannot change access
  enum E: int { e0 }; // error: cannot change access
};
end example
]
[Note
:
In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared.
The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared.
end note
]
[Example
:
class A { };
class B : private A { };
class C : public B {
  A* p;             // error: injected-class-name A is inaccessible
  ::A* q;           // OK
};
end example
]