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();
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.