Member access (C++ only)

Member access determines if a class member is accessible in an expression or declaration. Suppose x is a member of class A. Class member x can be declared to have one of the following levels of accessibility:

Members of classes declared with the keyword class are private by default. Members of classes declared with the keyword struct or union are public by default.

To control the access of a class member, you use one of the access specifiers public, private, or protected as a label in a class member list. The following example demonstrates these access specifiers:

struct A {
  friend class C;
private:
  int a;
public:
  int b;
protected:
  int c;
};

struct B : A {
  void f() {
    // a = 1;
    b = 2;
    c = 3;
  }
};

struct C {
  void f(A x) {
    x.a = 4;
    x.b = 5;
    x.c = 6;
  }
};

int main() {
  A y;
//  y.a = 7;
  y.b = 8;
//  y.c = 9;

  B z;
//  z.a = 10;
  z.b = 11;
//  z.c = 12;
}

The following table lists the access of data members A::a A::b, and A::c in various scopes of the above example.

Scope A::a A::b A::c
function B::f() No access. Member A::a is private. Access. Member A::b is public. Access. Class B inherits from A.
function C::f() Access. Class C is a friend of A. Access. Member A::b is public. Access. Class C is a friend of A.
object y in
main()
No access. Member y.a is private. Access. Member y.a is public. No access. Member y.c is protected.
object z in main() No access. Member z.a is private. Access. Member z.a is public. No access. Member z.c is protected.

An access specifier specifies the accessibility of members that follow it until the next access specifier or until the end of the class definition. You can use any number of access specifiers in any order. If you later define a class member within its class definition, its access specification must be the same as its declaration. The following example demonstrates this:

class A {
    class B;
  public:
    class B { };
};

The compiler will not allow the definition of class B because this class has already been declared as private.

A class member has the same access control regardless whether it has been defined within its class or outside its class.

Access control applies to names. In particular, if you add access control to a typedef name, it affects only the typedef name. The following example demonstrates this:

class A {
    class B { };
  public:
    typedef B C;
};

int main() {
  A::C x;
//  A::B y;
}

The compiler will allow the declaration A::C x because the typedef name A::C is public. The compiler would not allow the declaration A::B y because A::B is private.

Note that accessibility and visibility are independent. Visibility is based on the scoping rules of C++. A class member can be visible and inaccessible at the same time.

Related information