Skip to Content
Course content

115: Overloading the Increment and Decrement Operators

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

I once worked with a developer who was building a custom coordinate system for a 2D tile-based game. He had a Position class and wanted to be able to iterate through the map using a simple ++pos syntax. He spent an entire afternoon fighting the compiler because he couldn't figure out why his "increment" function wasn't being called. Then, once he finally got it working, he introduced a subtle bug where the game loop skipped every other tile. The culprit? He had implemented the postfix operator (pos++) but was returning the updated object by reference. In C++, that's a cardinal sin because postfix is explicitly supposed to return the state of the object before the increment happened.

When you overload the increment (++) and decrement (--) operators, you're dealing with one of the few cases in C++ where the language uses a "dummy" parameter to distinguish between two different versions of the same operator. You've likely used these in built-in types: the prefix version increments and then returns the result, while the postfix version returns the original value and then increments.

Distinguishing Prefix and Postfix Signatures

To the compiler, the prefix operator is a straightforward overload: T& operator++(). It takes no arguments and returns a reference to the current object. This is efficient because you just modify the internal state and return *this.

The postfix operator, however, looks like this: T operator++(int). That int parameter isn't actually used for anything; it's just a flag the compiler uses to tell the two apart. Notice the return type change here. Since the postfix operator must return the value as it was before the increment, you can't return a reference to the object itself (because the object is about to change). Instead, you must return a copy of the object by value.

class GridPosition {
    int x, y;
public:
    GridPosition(int x, int y) : x(x), y(y) {}

    // Prefix increment: ++pos
    GridPosition& operator++() {
        x++; // Move right
        return *this;
    }

    // Postfix increment: pos++
    GridPosition operator++(int) {
        GridPosition temp = *this; // Save current state
        ++(*this);                // Reuse the prefix operator!
        return temp;              // Return the old state
    }
};

The Logic of Decrementing and Efficiency

The decrement operator (--) follows the exact same pattern. You'll have a prefix version returning *this and a postfix version taking a dummy int and returning a copy. I always recommend a specific implementation trick: have your postfix operator call your prefix operator internally. As shown in the example above, ++(*this) inside the postfix method ensures that the actual increment logic only exists in one place. If you ever decide to change how "incrementing" works—say, adding a boundary check—you only have to change it in the prefix method.

One thing to keep in mind is performance. Because the postfix operator creates a temporary copy of the object, it is inherently slower than the prefix operator. When you're working with complex objects—like a custom iterator for a massive data structure—you should lean toward ++it instead of it++. In a tight loop, those unnecessary copies can actually add up and degrade your frame rate or processing time.




📋 Practical Task

Implementing a Circular Buffer Index Wrapper

You are tasked with creating a class called CircularIndex that wraps an integer. This index is used to traverse a circular buffer of a fixed size. When the index reaches the maximum size, incrementing it should wrap it back around to zero. Similarly, decrementing it should wrap it to the maximum size minus one.

Implement the CircularIndex class with the following requirements:

  • A constructor that takes the maxSize of the buffer.
  • A prefix increment operator (++) that increases the index and wraps it using the modulo operator.
  • A postfix increment operator (++) that returns the index before it was incremented.
  • A prefix decrement operator (--) that decreases the index and wraps it (ensure you handle negative results correctly so the index stays positive).
  • A method int getValue() const to retrieve the current index.

Test your implementation by creating a CircularIndex with a size of 5, incrementing it 6 times, and verifying that the final value is 1.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.