Lesson 6 | The operator keyword |
Objective | Learn how to use the operator keyword to overload operators in C++ |
operator
Keyword in C++
Operator overloading in C++ lets you redefine how operators behave for your own classes, providing more natural syntax for custom types.
The mechanism is implemented through the operator
keyword. However, it is critical to follow best practices: only overload
operators when it improves clarity, preserve expected semantics, and prefer return-by-reference when modifying objects.
Overloading an operator is similar to writing a function, except the function name is formed with the keyword operator
followed by the operator symbol:
class Foo {
public:
Foo operator-(); // unary minus
Foo operator-(int); // binary minus Foo - int
Foo operator-(const Foo&); // binary minus Foo - Foo
};
// non-member overload
Foo operator-(int, const Foo&); // int - Foo (legal)
// Foo operator-(int, Foo*); // illegal: must take Foo or Foo&
+ - * / = < > += -= *= /= << >>
<<= >>= == != <= >= ++ -- % & ^ ! |
~ &= ^= |= && || %= [] () , ->* ->
new delete new[] delete[]
Figure 3-6: Operators that can be overloaded
Operators that cannot be overloaded | |||
. | .* | :: | ?: |
Operator overloading cannot change the built-in precedence, associativity, or the number of operands:
?:
) cannot be overloaded.This means parentheses may be required for clarity when mixing overloaded and built-in operators.
Operator overloading can also define implicit type conversions. A class may declare a conversion operator that allows objects to be treated as another type:
class Three {
int i;
public:
explicit Three(int ii = 0) : i(ii) {}
};
class Four {
int x;
public:
Four(int xx) : x(xx) {}
operator Three() const { return Three(x); } // conversion operator
};
void g(Three) {}
int main() {
Four four(1);
g(four); // converted via operator Three()
g(1); // calls Three(int) constructor
}
Here, Four
defines an operator conversion to Three
.
This allows seamless use of Four
in contexts expecting Three
.
Unlike constructors, which perform conversion in the destination type, operator conversions
are defined in the source type. To avoid unintended implicit conversions, mark single-argument
constructors and conversion operators with explicit
.
operator+
should not modify operands).