Member functions method is commonly used to overload unary operators, assignment operator etc. In this method, the left side operand has to be a program defined type where member function for operator overload has been defined.

For example:

#include <iostream>
 
class Int
{
    int m_value{};
 
public:
    Int() = default;
    Int(int value)
        : m_value{value}
    {
    }
 
    Int &operator++()
    {
        m_value += 1;
        return *this;
    }
 
    Int operator++(int)
    {
        const Int temp{*this};
        m_value += 1;
        return temp;
    }
 
    Int &operator--()
    {
        m_value -= 1;
        return *this;
    }
 
    Int operator--(int)
    {
        const Int temp{*this};
        m_value -= 1;
        return temp;
    }
 
    friend std::ostream &operator<<(std::ostream &out, const Int &v);
};
 
std::ostream &operator<<(std::ostream &out, const Int &v)
{
    return out << v.m_value;
}
 
int main(int argc, char const *argv[])
{
 
    Int v{1};
 
    std::cout << ++v << '\n';
    std::cout << v++ << '\n';
    std::cout << --v << '\n';
    std::cout << v-- << '\n';
 
    return 0;
}

Interesting things to note in this program are how prefix and postfix variations for ++ and -- are implemented.

Overloading both operators require no argument so there is no way to differentiate prefix and postfix. So, C++ takes this as a special case where a dummy int parameter is used to differentiate prefix from postfix.

Prefix notation is straightforward where we increment/decrement the object and return by reference. On the other hand, in postfix notation, we need to create a temporary object by copying the object and then increment the object. This temporary object is then returned by value.

This is why, postfix notation is inefficient than prefix because it involves creation of temporary objects.

References

  1. https://www.learncpp.com/cpp-tutorial/overloading-operators-using-member-functions/