C++ Accessing class members


Example

To access member variables and member functions of an object of a class, the . operator is used:

struct SomeStruct {
  int a;
  int b;
  void foo() {}
};

SomeStruct var;
// Accessing member variable a in var.
std::cout << var.a << std::endl;
// Assigning member variable b in var.
var.b = 1;
// Calling a member function.
var.foo();

When accessing the members of a class via a pointer, the -> operator is commonly used. Alternatively, the instance can be dereferenced and the . operator used, although this is less common:

struct SomeStruct {
  int a;
  int b;
  void foo() {}
};

SomeStruct var;
SomeStruct *p = &var;
// Accessing member variable a in var via pointer.
std::cout << p->a << std::endl;
std::cout << (*p).a << std::endl;
// Assigning member variable b in var via pointer.
p->b = 1;
(*p).b = 1;
// Calling a member function via a pointer.
p->foo();
(*p).foo();

When accessing static class members, the :: operator is used, but on the name of the class instead of an instance of it. Alternatively, the static member can be accessed from an instance or a pointer to an instance using the . or -> operator, respectively, with the same syntax as accessing non-static members.

struct SomeStruct {
  int a;
  int b;
  void foo() {}

  static int c;
  static void bar() {}
};
int SomeStruct::c;

SomeStruct var;
SomeStruct* p = &var;
// Assigning static member variable c in struct SomeStruct.
SomeStruct::c = 5;
// Accessing static member variable c in struct SomeStruct, through var and p.
var.a = var.c;
var.b = p->c;
// Calling a static member function.
SomeStruct::bar();
var.bar();
p->bar();

Background

The -> operator is needed because the member access operator . has precedence over the dereferencing operator *.

One would expect that *p.a would dereference p (resulting in a reference to the object p is pointing to) and then accessing its member a. But in fact, it tries to access the member a of p and then dereference it. I.e. *p.a is equivalent to *(p.a). In the example above, this would result in a compiler error because of two facts: First, p is a pointer and does not have a member a. Second, a is an integer and, thus, can't be dereferenced.

The uncommonly used solution to this problem would be to explicitly control the precedence: (*p).a

Instead, the -> operator is almost always used. It is a short-hand for first dereferencing the pointer and then accessing it. I.e. (*p).a is exactly the same as p->a.

The :: operator is the scope operator, used in the same manner as accessing a member of a namespace. This is because a static class member is considered to be in that class' scope, but isn't considered a member of instances of that class. The use of normal . and -> is also allowed for static members, despite them not being instance members, for historical reasons; this is of use for writing generic code in templates, as the caller doesn't need to be concerned with whether a given member function is static or non-static.