Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Operator overloading : member function vs. non-member function?

People also ask

When should you consider using non-member overload operators for your operators?

The rules are applied in order. An overloaded operator will be used if either of the two rules is satisfied. When operator overloading is achieved using non-member function there are two cases to be considered: the overloaded operator uses only the public interface of the class(es) involved in the overloading, or.

Can member functions be overloaded?

Function declarations that differ only by its return type cannot be overloaded with function overloading process. Member function declarations with the same parameters or the same name types cannot be overloaded if any one of them is declared as a static member function.

Which of the following operators can be overloaded both as class member functions and as non-member functions?

Operators which can be overloaded either as members or as non-members. This is the bulk of the operators: The pre- and post-increment/-decrement operator++() , operator--() , operator++(int) , operator--(int) The [unary] dereference operator*()

Which operator Cannot be overloaded using member function?

Operators that cannot be overloaded are . . * :: ?: Operator cannot be used to overload when declaring that function as friend function = () [] ->.


If you define your operator overloaded function as member function, then the compiler translates expressions like s1 + s2 into s1.operator+(s2). That means, the operator overloaded member function gets invoked on the first operand. That is how member functions work!

But what if the first operand is not a class? There's a major problem if we want to overload an operator where the first operand is not a class type, rather say double. So you cannot write like this 10.0 + s2. However, you can write operator overloaded member function for expressions like s1 + 10.0.

To solve this ordering problem, we define operator overloaded function as friend IF it needs to access private members. Make it friend ONLY when it needs to access private members. Otherwise simply make it non-friend non-member function to improve encapsulation!

class Sample
{
 public:
    Sample operator + (const Sample& op2); //works with s1 + s2
    Sample operator + (double op2); //works with s1 + 10.0

   //Make it `friend` only when it needs to access private members. 
   //Otherwise simply make it **non-friend non-member** function.
    friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}

Read these :
A slight problem of ordering in operands
How Non-Member Functions Improve Encapsulation


It's not necessarily a distinction between friend operator overloads and member function operator overloads as it is between global operator overloads and member function operator overloads.

One reason to prefer a global operator overload is if you want to allow expressions where the class type appears on the right hand side of a binary operator. For example:

Foo f = 100;
int x = 10;
cout << x + f;

This only works if there is a global operator overload for

Foo operator + (int x, const Foo& f);

Note that the global operator overload doesn't necessarily need to be a friend function. This is only necessary if it needs access to private members of Foo, but that is not always the case.

Regardless, if Foo only had a member function operator overload, like:

class Foo
{
  ...
  Foo operator + (int x);
  ...
};

...then we would only be able to have expressions where a Foo instance appears on the left of the plus operator.