Skip to Content
Course content

35: Operator Overloading: Arithmetic Operators

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've seen this happen a dozen times with developers moving from Python or JavaScript to C++. You build a class to represent a concept—like a 2D coordinate or a currency value—and then you try to use it naturally in a mathematical expression. It feels like it should just work, but then the compiler hits you with a wall of errors.

struct Vector2D {
    float x, y;
};

int main() {
    Vector2D pos1 = {10.0f, 5.0f};
    Vector2D pos2 = {2.0f, 3.0f};
    
    // This line triggers a massive compiler error
    Vector2D result = pos1 + pos2; 
    
    return 0;
}

Why the compiler doesn't know how to add Vectors

The error you'll see usually says something like no match for 'operator+'. To the C++ compiler, Vector2D is just a chunk of memory containing two floats. It has no idea that "adding" two vectors means adding the x values together and the y values together. It doesn't assume you want a component-wise addition because, in some contexts, "adding" two objects might mean merging lists or appending strings.

You could fix this by writing a function like Vector2D add(Vector2D a, Vector2D b), but that makes your code clunky. Writing pos1 + pos2 is far more readable than add(pos1, pos2), especially when you start chaining operations together. This is where operator overloading comes in.

Teaching C++ the addition rule

To fix this, we define a special function called operator+. When the compiler sees the + symbol between two Vector2D objects, it will look for this function and call it instead.

struct Vector2D {
    float x, y;

    // We overload the + operator
    Vector2D operator+(const Vector2D& other) const {
        return {x + other.x, y + other.y};
    }
};

Notice a few critical things here. First, I'm returning a new Vector2D. A common mistake I see is developers trying to modify the current object inside operator+. Don't do that. In mathematics, a + b = c doesn't change a or b. If you want to modify the object, that's what operator+= is for (which we'll hit later).

Second, I used const Vector2D& other. We pass by reference to avoid copying the object unnecessarily, and we mark it const because adding two vectors shouldn't change the values of the vectors being added. Finally, the const at the end of the function signature tells C++ that this method doesn't modify the object it's called on.

Handling scalar multiplication

Arithmetic isn't just about adding two identical types. Often, you'll want to multiply a vector by a number (a scalar) to scale it. This requires a slightly different approach because the left-hand side of the operation is a float, not a Vector2D.

If we put the operator inside the class, the left-hand side must be a Vector2D. To allow float * Vector2D, we define the operator as a non-member function:

struct Vector2D {
    float x, y;

    Vector2D operator+(const Vector2D& other) const {
        return {x + other.x, y + other.y};
    }
};

// Non-member function for scalar multiplication
Vector2D operator*(float scalar, const Vector2D& vec) {
    return {vec.x * scalar, vec.y * scalar};
}

// Now this works:
Vector2D pos = {1.0f, 2.0f};
Vector2D scaled = 2.0f * pos; 

I personally prefer keeping arithmetic operators as simple as possible. If the logic inside your operator+ starts getting complex (like involving database calls or heavy logging), you're probably overloading the operator when you should have just written a named function. Use overloading for things that mathematically feel like the operator they are replacing.




📋 Practical Task

Implementation: Complex Number Arithmetic Library

In mathematics, complex numbers consist of a real part and an imaginary part. Adding two complex numbers involves adding their real parts together and their imaginary parts together. Subtracting follows the same logic.

Your Task: Create a class ComplexNumber that allows for natural arithmetic. Implement the following:

  • Two private member variables: double real and double imag.
  • A constructor to initialize these values.
  • An overloaded operator+ to return the sum of two ComplexNumber objects.
  • An overloaded operator- to return the difference between two ComplexNumber objects.
  • A method display()` that prints the number in the format a + bi.

Test Case: If you add (3.0, 2.0) and (1.0, 7.0), the result should be (4.0, 9.0). If you subtract the latter from the former, the result should be (2.0, -5.0).

Rating
0 0

There are no comments for now.

to be the first to leave a comment.