C++ Operator Precedence and the Arrow Operator

Learn more about pointers, and how we can use the arrow operator to make our code more readable
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

3D art showing a female blacksmith character
Ryan McCombe
Ryan McCombe
Posted

With everything we've learned about pointers, we no longer need to create so many global variables.

For example, we can create a variable in one function, and give another function a pointer to access and modify it:

1void Combat(Character* A, Character* B) {
2  (*A).TakeDamage(50);
3  (*B).TakeDamage(50);
4}
5
6int main() {
7  Character Player;
8  Monster Monster;
9  Combat(&Player, &Monster);
10}
11

In the above example, it is worth talking about Line 2 in a bit more detail: (*A).TakeDamage(50);

Specifically, why have we wrapped the *A in brackets?

The reason we have added brackets here is to control the order of operations.

Had we written *A.TakeDamage(50), our intentions might be clear to us - dereference A then call TakeDamage. But it could also be interpreted as call A.TakeDamage then try to dereference the result.

If we put this code into our editor, it would become clear by the error, that the compiler is trying to do the latter. This is due to rules around operator precedence.

Operator Precedence in C++

In maths classes, we may have learnt that different operators have different precedences. We don't always do things left-to-right.

For example, multiplication happens before addition. Therefore 1 + 2 * 3 is equal to 7, not 9;

This concept also applies to operators in programming languages.

The member access . operator has higher precedence than the dereferencing operator * in C++. So, when we have a statement that combines both operations, . will happen before *.

When we had the statement *A.TakeDamage(50), it was equivalent to *(A.TakeDamage(50)). With A being a pointer - we can't use the . operator on it, so the compiler reported the error.

What's the precedence of the other operators?

It's not important to know the precedence of all the operators. Even among professional developers, very few will have commited that to memory, because it's so easy to look up when it's needed.

The important thing to know is the concept: operators have different precedences, and we can add brackets to control it.

That being said, the precedence of all operators in C++ is given here: https://en.cppreference.com/w/cpp/language/operator_precedence

Reviewing the table at that website explains a quirk we saw the the previous lesson, where we had the code snippets (*x)++; and *x *= 2;

Why did the first statement need ( and ) but the second one didn't? It was because * has lower precedence than ++, but higher precedence than *=.

The C++ Arrow Operator: ->

In the previous example, where A is a pointer to an object, and we needed to access a member of that object, we used this pattern:

(*A).TakeDamage(50);

C++ does have an alternative to this, called the arrow operator:

A->TakeDamage(50);

This is much more common, therefore, it will be our preferred approach going forward.

Note, we only use the -> operator with pointers to an object. When we have the actual object, or a reference to it, the . operator must still be used to access its members.

// We use . with objects
Character MyCharacter;
MyCharacter.TakeDamage(50);

// We use . with references
Character& Reference { MyCharacter };
Reference.TakeDamage(50);

// We use -> with pointers
Character* Pointer { &MyCharacter };
Pointer->TakeDamage(50);

Test your Knowledge

Given the following code, what could we put on line 7 to call the Equip function of the Weapon passed in as a parameter?

1class Weapon {
2public:
3  void Equip() {}
4};
5
6void PrepareForBattle(Weapon SelectedWeapon) {
7  // ???
8}
9

Given the following code, what could we put on line 7 to call the Equip function of the Weapon passed in as a parameter?

1class Weapon {
2public:
3  void Equip() {}
4};
5
6void PrepareForBattle(Weapon& SelectedWeapon) {
7  // ??
8}
9

Given the following code, what could we put on line 7 to call the Equip function of the Weapon passed in as a parameter?

1class Weapon {
2public:
3  void Equip() {}
4};
5
6void PrepareForBattle(Weapon* SelectedWeapon) {
7  // ??
8}
9

Was this lesson useful?

Ryan McCombe
Ryan McCombe
Posted
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

References and Pointers
3D art showing a progammer setting up a development environment
This lesson is part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access!

This course includes:

  • 66 Lessons
  • Over 200 Quiz Questions
  • Capstone Project
  • Regularly Updated
  • Help and FAQ
Next Lesson

References and Pointers to Local C++ Variables

Explanation of automatic storage duration, and why it is important to consider when returning pointers and references from functions
3D art showing a female blacksmith character
Contact|Privacy Policy|Terms of Use
Copyright © 2023 - All Rights Reserved