C++ Operator Overloading

Learn how we can enhance our classes and structs by letting them define their our own operators.
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 fantasy character
Ryan McCombe
Ryan McCombe
Posted

In the previous lesson, we created a simple Vector3 struct to hold 3 numbers, represending a 3D position:

struct Vector3 {
  float x;
  float y;
  float z;
}

It would be nice if we were able to use operators like + and += with our new custom type, in much the same way we were able to do with types like int and float.

For example, we would like to be able to do things like this:

Vector3 CurrentPosition { 1.0, 2.0, 3.0 };
Vector3 Movement { 4.0, 5.0, 6.0 };

// Create a new object using the + operator
Vector3 NewPosition { CurrentPosition + Movement };

After running the above code, we'd want NewPosition to be a Vector3 with the values 5.0, 7.0 and 9.0.

We'd also like to be able to do the following, to update the CurrentPosition vector directly:

Vector3 CurrentPosition { 1.0, 2.0, 3.0 };
Vector3 Movement { 4.0, 5.0, 6.0 };

// Update an existing object using the += operator
CurrentPosition += Movement;

For this, we need to overload operators.

C++ Operators are Functions

In C++, operators are simply functions that have a specific name and parameter list.

When we write code like 1 + 2, the compiler is going to try to call a function with the following properties:

  • Has a name of operator+
  • Accepts an int as the first argument
  • Accepts an int as the second argument

With that in mind, lets create a function to be the + operator that can be used with two Vector3 objects:

void operator+ (Vector3 a, Vector3 b) {

}

With those additions, we can now write the following code, and have our program compile successfully:

CurrentPosition + Movement;

Of course, we want that expression to actually return a useful value. So, lets implement our function, by updating its return type, and adding an appropriate return statement:

Vector3 operator+ (Vector3 a, Vector3 b) {
  return Vector3 { a.x + b.x, a.y + b.y, a.z + b.z };
}

With that, we can now easily add our Vector3 objects together!

There are some improvements we can make. Our function is currently accepting the structs by value. We can change this to be pass by reference instead, as we have no need to create a copy of our incoming objects.

Further, since our operator is not modifying the input objects, we can make those references const.

Vector3 operator+ (const Vector3& a, const Vector3& b) {
  return Vector3 { a.x + b.x, a.y + b.y, a.z + b.z };
}

Test your Knowledge

What function signature would we need to make line 4 work?

1Vector3 CurrentPosition { 1.0, 2.0, 3.0 };
2Vector3 Reverse { 4.0, 5.0, 6.0 };
3
4Vector3 NewPosition { CurrentPosition - Reverse };
5

What function would we need to allow a vector to be multiplied by an integer?

1Vector3 CurrentPosition { 1.0, 2.0, 3.0 };
2
3Vector3 NewPosition { CurrentPosition * 5 };
4

Overloading C++ Operators with Member Functions

The previous examples implemented operator overloading using a standalone function. However, it is also possible to implement it by having our function be a member of our struct or class.

Lets see what the + operator might look like using that method:

struct Vector3 {
  float x;
  float y;
  float z;
  
  Vector3 operator+ (const Vector3& Other) {
    return Vector3 {
      x + Other.x,
      y + Other.y,
      z + Other.z
    };
  }
};
Vector3 MyVector { 1.0, 2.0, 3.0 };
Vector3 OtherVector { 1.0, 2.0, 3.0 };
Vector3 CombinedVector { MyVector + OtherVector };

The key thing to note in the declaration of operator+ within the struct is that there is only one parameter.

This might be confusing, as the + operator has two operands - a left and a right. Indeed, when we created this as a standalone function earlier, we needed to have two parameters:

Vector3 operator+ (const Vector3& a, const Vector3& b) {
  return Vector3 { a.x + b.x, a.y + b.y, a.z + b.z };
}

However, when when we overload the operator as a member function, the function is called within the context of the left operand. Therefore, there is no need to have the left operand be provided as an argument - we can just access its class members in the same way we would any other class function.

Test your Knowledge

How can we allow our Vector3 objects to be multiplied with a float using a member function operator overload?

struct Vector3 {
  float x;
  float y;
  float z;
  
  // Add a function here
};

Vector3 MyVector { 4.0, 5.0, 6.0 };
Vector3 BigVector { MyVector * 3 };

Like any other class or struct function, we can declare and define them in different locations, if we want. This would be useful if we want to have a seperate .h and .cpp file:

// Header File
struct Vector3 {
  float x;
  float y;
  float z;
  
  Vector3 operator+ (const Vector3& Other);
};
// CPP File
Vector3 Vector3::operator+ (const Vector3& Other) {
  return Vector3 {
    x + Other.x,
    y + Other.y,
    z + Other.z
  };
}

This lesson focused on overloading binary operators. Binary operators are those that take two operands - a left and a right.

We've also seen unary operators in the past, like ++, *= and !. These operators only operate on one object.

We'll see how we can overload those in the next lesson!

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

Namespaces, Enums and Structs
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

Overloading Unary Operators in C++

Learn how to enhance our C++ classes and structs by overloading unary operators such as ++ and --
3D art showing a fantasy pirate character
Contact|Privacy Policy|Terms of Use
Copyright © 2023 - All Rights Reserved