We generally use the following two methods to overload operators:
- Member Functions
- Non-member functions
In fact, these two definitions are not only syntactic, but also semantic. In syntax, it is defined as a member function, such as operator + =. Only one parameter is accepted, and a non-member function accepts two parameter semantics. This involvesThe temporary object cannot be bound to the left-side reference.For example, we need to reload operator ++ =, operator ++
struct foo{#ifndef NON_MEMBER_OPERATOR foo& operator +=(const foo& rhs) { return *this; } foo& operator ++() { return *this; }#endif};#ifdef NON_MEMBER_OPERATORfoo& operator +=(foo& lhs, const foo& rhs){ return lhs;}foo& operator ++(foo& lhs){ return lhs;}#endif
Here, if we use a member function, we can call operator ++ = or operator ++ on a temporary object.
foo() += foo();++foo();
This statement can be compiled. But in general, we do not want to modify the temporary object, because the modification is usually lost with the destruction of the temporary object. When a non-member function is used, the preceding statement cannot be compiled because the temporary object cannot be bound to the left value reference. This is generally in line with our requirements and is easier to prevent misuse. Therefore, for mutating Operator overloading, we prefer the form of non-member functions.