Unary and Binary Operators
An overloaded arithmetic operator is a function whose name is the operator symbol, such as operator+, and whose body defines what the operator means for the user-defined type.
Why Operators Need Definitions for New Types
A built-in type such as a number already has meaning for the plus sign. When you build your own type, such as a complex number, the language does not automatically know what it means to add two of your values or to subtract one from another. Operator overloading is the mechanism that lets you attach your own behavior to an operator symbol when its operands are your type.
What do you think happens?
Suppose a caller holds two complex values, x and y, and writes z = x + y. The + dispatches to an operator+ definition that updates a copy of its first parameter and returns it. After the expression finishes, what does z hold, and what does x hold?
Reveal answer
z receives the value returned by operator+, which is the updated copy of the first operand. x still holds its original value.
The definition works on a copy of x, so the caller's x is never modified. The returned value is what carries the result out to z.
What an Overloaded Operator Definition Is
An overloaded arithmetic operator is a function whose name is the operator symbol, such as operator+, and whose body defines what the operator means for the user-defined type.
Read each definition as a small contract: it takes complex values as input and returns a complex value as output. Two questions govern every such definition. First, which values are the inputs, which is determined by the parameter list. Second, which value comes back to the caller, which is determined by the return statement. The body is where the arithmetic actually happens, and it is the part that keeps the caller's values intact.
The name of the function is built from the operator symbol. The addition definition is named operator+, the subtraction definition is named operator-, and so on. Because the name is the symbol, a caller who writes an expression with that symbol causes the matching definition to run.
Tracing a Call to operator+
Start with the addition definition. Its name is operator+, and it accepts two parameters, both of type complex. The body does not compute a fresh sum in a separate variable. Instead, it applies the compound assignment a += b to the first parameter and returns the result. Here is the definition written in the C++-style form the source uses.
- The two parameters a and b are the operands; both arrive by value, so each is a copy.
- a += b updates the copy named a, not the caller's variable.
- return a sends the updated copy back to the caller as the result of the expression.
Predicting z after z = x + y
Let x be the complex value with real part 1 and imaginary part 2, and let y be the complex value with real part 3 and imaginary part 4. Trace operator+ and find the value of z and the value of x after the statement finishes. These specific values are an illustrative choice and are not taken from the source.
- 1Step 1: Pass by value
operator+ receives copies. Parameter a is a copy of x, and parameter b is a copy of y. The caller's x and y are not handed over directly.
- 2Step 2: Apply the compound assignment
The body executes a += b on the copy a. Adding complex values adds their real parts and their imaginary parts, so a changes from 1 plus 2i to 4 plus 6i. The copy b is unchanged.
- 3Step 3: Return the updated copy
The function returns a, which now holds 4 plus 6i. This return value is what the expression produces.
- 4Step 4: Assign to z
The caller stores the returned value in z, so z holds 4 plus 6i.
- 5Step 5: Check the caller's x
The copy a was the thing that changed. The caller's x still holds 1 plus 2i.
z holds 4 plus 6i, and x still holds 1 plus 2i.
Why the Caller's Values Stay Intact
The reason the caller's x is unchanged is pass by value. Arguments passed by value are copied, so the function can modify its parameter freely without changing the caller's value. The operator works on the copy, and the copy is discarded once the function ends. What survives is only the value the function returns.
The Binary Definitions Share One Pattern
A binary operator takes two operands, so its definition has two parameters. The source gives the same pattern for subtraction, multiplication, and division. Each body performs the matching compound assignment on the first parameter and returns it. Only the operator symbol and the compound assignment change; the structure stays the same.
| Operator definition | Parameters | Compound assignment on first parameter | Returned value |
|---|---|---|---|
| operator+ | two complex values | a += b | the updated copy a |
| operator- | two complex values | a -= b | the updated copy a |
| operator* | two complex values | a *= b | the updated copy a |
| operator/ | two complex values | a /= b | the updated copy a |
The four binary arithmetic definitions differ only in their symbol and compound assignment.
The source also defines equality and inequality, noting that the definitions of == and != are straightforward. Its bodies are not given in the material, so this article does not present them. What you can rely on is the arithmetic pattern: two operands come in by value, the first is updated through a compound assignment, and the updated copy goes out as the return value.
The Unary Minus Definition
A unary operator takes exactly one operand. Unary minus has a different shape from the binary definitions. Its parameter list has a single complex value, and its body does not use a compound assignment. Instead, it builds and returns a new complex value whose real part is the negation of the original real part and whose imaginary part is the negation of the original imaginary part.
Here a_r is the real part of a and a_i is its imaginary part. The result of unary minus is the pair (-a_r, -a_i). Notice what does not happen in this case. The operand is not modified in place as a compound assignment would do. The function constructs a fresh value and hands it back. This is the contrast with the binary definitions, where the copy of the first operand is the thing being updated.
Mistakes Beginners Make With Operator Definitions
Common mistake Expecting the caller's x to change after z = x + y
What it looks likeAfter z = x + y, assuming x now holds the sum.
Why it failsArguments are passed by value and copied, so the operator updates only its copy of the first operand.
Do this insteadRead the result from z, which receives the returned value. The caller's x keeps its original value.
Common mistake Treating a unary definition like a binary one
What it looks likeLooking for a second parameter in operator-(x) and expecting a compound assignment in its body.
Why it failsA unary operator takes exactly one operand, and unary minus builds and returns a new value rather than updating a parameter.
Do this insteadCount the parameters first. One parameter means a unary definition that returns a new value built from the negated parts.
Common mistake Forgetting the return statement
Why it failsThe result reaches the caller only through the returned value, so a definition that only updates its parameter sends nothing back.
Common mistake Assuming == and != follow the same body as + without checking the definition
Suppose z = x + y produces a value that is wrong, and the caller's x looks wrong too. Follow the value from the operands through the body to the return. If the copies a and b are correct on entry, the first wrong value appears in the compound assignment on a. If a is already wrong when the function is entered, the error sits in the caller's expression. Check the compound assignment line first, because it is the single place where the first operand's value changes inside the operator.
Trace the Subtraction Definition Yourself
Assume operator- follows the same pattern as operator+, with the body a -= b followed by return a. Let x be 5 plus 1i and y be 2 plus 3i. Trace z = x - y and state the value of z and the value of x after the statement finishes. Then state how many parameters operator-(x) would need if it were the unary form, and what it would return.
Hints
- Pass by value means the function works on copies of x and y.
- The compound assignment a -= b subtracts the real parts and the imaginary parts separately.
- The caller's x is never modified, so x should still hold 5 plus 1i at the end.
- A unary definition takes one parameter and returns a new value rather than updating its parameter.
Key Takeaways
- An overloaded arithmetic operator is a function named by its symbol, such as operator+, whose body defines what the operator means for a user-defined type.
- Arguments passed by value are copied, so a binary definition can update its first parameter without changing the caller's value; the returned value carries the result out.
- Binary definitions such as operator+, operator-, operator*, and operator/ perform a matching compound assignment on the first parameter and return it.
- The unary minus definition takes one operand and returns a new value with negated real and imaginary parts, that is (-a_r, -a_i), rather than modifying the operand.
- When an operator returns an unexpected value, check the compound assignment inside the body first, since that is where the first operand's value changes.