What is operator overloading? Operator overloading is the practice of assigning new meaning to existing C++ operators when they are used with user defined types.
The language already understands what + means for 2 ints or 2 doubles. When you define a class, you can instruct the compiler what + (or -, ==, <<, and many others) means for objects of that class. The operator is still written as the (+) symbol, but secretly the compiler invokes a function you provide.
This is how you name a function by prefixing the symbol with the keyword operator. For addition, it would become operator+. So an addition expression would be turned by the compiler into a call to operator+ or, if the operator was a member function, into a call to member operator+. Both are legal; the compiler chooses accordingly.
Point result = a + b;
The compiler can interpret this as a call to the non member operator:
// Define how this operator works for the class
Point result = operator+(a, b);
Or, if the operator is a member function:
Point result = a.operator+(b);
For instance, the following minimal complete example overloads + for a very simple two dimensional point.
#include <iostream>
struct Point
{
int x{};
int y{};
};
// Bind by reference without allowing modification through it
Point operator+(const Point& lhs, const Point& rhs)
{
return Point{ lhs.x + rhs.x, lhs.y + rhs.y };
}
int main()
{
Point a{ 2, 3 };
Point b{ 4, 5 };
Point c{ a + b };
std::cout << c.x << ' ' << c.y << '\n';
return 0;
}
The free function operator+ takes the left hand operand as lhs and the right hand operand as rhs. The two operands are taken by const reference so that neither is copied. Inside the function, a new Point is returned with the new Point's x value being the sum of the two x values and the new Point's y value being the sum of the two y values. That is returned by value to initialize c.
Since operator is a normal function, the same principles still hold: parameters can be passed either by value or by reference, the function may be declared const where needed, the return type may be anything that makes sense for the operation.
A few limitations are established by the language and can't be modified:
You may overload only existing operators; you cannot create a new symbol, e.g. **, as an operator.
One operand is of user defined type.
Number of operands, the precedence, and the associativity remain exactly the same as for the built in operator.
With these rules, if the overloaded operator does what can be naturally suggested by the symbol, client code can be shorter, more readable, and still be... Normal function calls!
Exercise: Introduction to Operator OverloadingStarter code, hints and solutionOpenClose
Practice: Introduction to Operator Overloading
Work through the mission, reveal hints only when needed, and compare your result with the model solution.
Your challenge
Add an explicit operator+(a, Point{1,1}) call and print the returned coordinates. Explain how the operands map to the free function parameters.
Mission checklist
- Run the starter as a baseline, then predict the change requested in Your challenge.
- Make that change in your editor; use the lesson-specific hints if you need help.
- Compile and run your answer, then compare with the worked solution and explain the result.
Starter program
This is the working baseline, not the completed answer. Compile as C++20, then make the change described above.
#include <iostream>
struct Point
{
int x{};
int y{};
};
// Bind by reference without allowing modification through it
Point operator+(const Point& lhs, const Point& rhs)
{
return Point{ lhs.x + rhs.x, lhs.y + rhs.y };
}
int main()
{
Point a{ 2, 3 };
Point b{ 4, 5 };
Point c{ a + b };
std::cout << c.x << ' ' << c.y << '\n';
return 0;
}Hints
operator+ is a free function taking two Points. Translate a + b into operator+(a, b) and match a to lhs and b to rhs.
Add the x coordinates separately from the y coordinates to construct c. The const references mean this addition does not change either input Point.
Worked solution
The extra call spells the overload explicitly as operator+(a, Point{1, 1}). It adds corresponding coordinates, returning a new Point (3,4) without changing a.
#include <iostream>
struct Point
{
int x{};
int y{};
};
// Bind by reference without allowing modification through it
Point operator+(const Point& lhs, const Point& rhs)
{
return Point{ lhs.x + rhs.x, lhs.y + rhs.y };
}
int main()
{
Point a{ 2, 3 };
Point b{ 4, 5 };
Point c{ a + b };
std::cout << c.x << ' ' << c.y << '\n';
Point d{operator+(a, Point{1, 1})};
std::cout << "Named call: " << d.x << ' ' << d.y << '\n';
return 0;
}
Example output
6 8
Named call: 3 4
0 comments
No comments yet. Be the first.