Operator overloading
In C++ an operator like + or == on your own class is a function call in disguise: the compiler turns a + b into operator+(a, b). Build a small Vec2 type with four operators, watch the values travel into each function and the result travel out, and learn when an operator should be a member, when it should be a free function, and which rules you cannot break.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01Vec2 has a free function Vec2 operator+(const Vec2&, const Vec2&). What does the compiler do with a + b?
For an operand of class type, an operator expression is a function call. a + b becomes operator+(a, b), and the expression's value is what that function returns.
02Why does operator+ take its parameters as const Vec2& rather than Vec2?
The & makes each parameter a reference, another name for the caller's object, so nothing is copied. const means the function cannot modify them, which is what you expect from +.
03What should operator+= return, and why?
a += b changes a itself. Returning *this by reference gives back a, just as x += 1 gives back x for an int, so expressions like (a += b) += c keep working.
04Why is operator<< for printing a Vec2 written as a free function and not as a member of Vec2?
A member operator gets its left operand as *this. In std::cout << c the left operand is the stream, which you cannot add members to, so the operator is the free function operator<<(std::ostream&, const Vec2&).
05Which of these can you NOT do with operator overloading?
You can only overload the operators the language already has. New symbols such as ** cannot be created, and :: . .* and ?: cannot be overloaded at all.
Glossary
- Operator overloading
- Giving an operator such as +, == or << a meaning for your own type by writing a function named operator followed by the symbol.
- Operator function
- A function whose name is operator plus a symbol, such as operator+. The compiler calls it when the operator is used on your type.
- Operand
- A value an operator works on. In a + b, a is the left operand and b is the right operand.
- Member function
- A function declared inside a class. It is called on an object, which it can reach as *this.
- Free function
- A function declared outside any class (also called a non-member function). Both operands arrive as ordinary parameters.
- Reference (&)
- Another name for an existing object. Passing by reference avoids a copy; const T& also forbids changes.
- *this
- Inside a member function, the object the function was called on. Returning *this by reference gives that object back.
- Defaulted comparison
- A C++20 feature: bool operator==(const T&) const = default; makes the compiler compare the members one by one.
Notes and sources
- For an expression a @ b where an operand has class or enumeration type, the compiler looks for both a member a.operator@(b) and a free operator@(a, b), and overload resolution picks the best match.
- A common pattern on cppreference writes operator+= as a member and then operator+ as a free function that copies its left operand and applies +=, so the arithmetic lives in one place.
- C++ Core Guidelines C.161: use non-member functions for symmetric operators like + and ==, so both operands are treated the same way, including implicit conversions.
- Defaulted comparisons (= default) and the rewriting of a != b into !(a == b) are both new in C++20. Before C++20 you wrote operator== and operator!= by hand.
- cppreference: ::, ., .* and ?: cannot be overloaded; new operators such as ** cannot be created; precedence, grouping and the number of operands cannot change; overloaded && and || lose short-circuit evaluation.
- An operator function must be a member, or take at least one parameter of class or enumeration type (or a reference to one). int operator+(int, int) is rejected by the compiler.
- The card's five lines are the body of main in a complete program that defines Vec2 and its four operators. It compiles without warnings with g++ -std=c++20 -Wall -Wextra and prints (4, 6).
- cppreference.com: Operator overloading
- cppreference.com: Default comparisons (C++20)
- cppreference.com: Overload resolution (rewritten candidates)
- cppreference.com: Reference declaration
- cppreference.com: The this pointer
- C++ draft standard: [over.oper] Overloaded operators
- Standard C++ Foundation (isocpp.org): Operator overloading FAQ
- C++ Core Guidelines (isocpp.github.io): C.161, use non-member functions for symmetric operators
- C++ Core Guidelines (isocpp.github.io): C.160, define operators primarily to mimic conventional usage
Quiz Unlocks after the last step.