Member selection for structs and references to structs
In lesson 13.7 -- Introduction to structs, members, and member selection, we showed that you can use the member selection operator (.) to select a member from a struct object:
Since references to an object act just like the object itself, we can also use the member selection operator (.) to select a member from a reference to a struct:
Member selection for pointers to structs
However, the member selection operator (.) can’t be used directly on a pointer to a struct:
With normal variables or references, we can access objects directly. However, because pointers hold addresses, we first need to dereference the pointer to get the object before we can do anything with it. So one way to access a member from a pointer to a struct is as follows:
However, this is a bit ugly, especially because we need to parenthesize the dereference operation so it will take precedence over the member selection operation.
To make for a cleaner syntax, C++ offers a member selection from pointer operator (->) (also sometimes called the arrow operator) that can be used to select members from a pointer to an object:
This member selection from pointer operator (->) works identically to the member selection operator (.) but does an implicit dereference of the pointer object before selecting the member. Thus ptr->id
is equivalent to (*ptr).id
.
This arrow operator is not only easier to type, but is also much less prone to error because the indirection is implicitly done for you, so there are no precedence issues to worry about. Consequently, when doing member access through a pointer, always use the -> operator instead of the . operator.
Best practice
When using a pointer to access a member, use the member selection from pointer operator (->) instead of the member selection operator (.).
Chaining operator->
If the member accessed via operator->
is a pointer to a class type, operator->
can be applied again in the same expression to access the member of that class type.
The following example illustrates this (courtesy of reader Luna):
When using more than one operator->
in sequence (e.g ptr->c->y
), the expression can be hard to read. Adding whitespace between the members and operator->
(e.g. ptr -> c -> y
) can make it a bit easier to distinguish the members being accessed from the operator.
Mixing pointers and non-pointers to members
The member selection operator is always applied to the currently selected variable. If you have a mix of pointers and normal member variables, you can see member selections where . and -> are both used in sequence:
Note that in the case of (ptr->paw).claws
, parentheses aren’t necessary since both operator->
and operator.
evaluate in left to right order, but it does help readability slightly.