The assignment operator can be overloaded using a member function but not a non-member friend
function:
class Test
{
int a;
public:
Test
This post applies to C++11
Why would someone want a non-member operator=
? Well, with a member operator=
then the following code is possible:
Test const &ref = ( Test() = something );
which creates a dangling reference. A non-member operator would fix this:
Test& operator=(Test &obj1, Test obj2)
because now the prvalue Test()
will fail to bind to obj1
. In fact this signature would enforce that we never return a dangling reference (unless we were supplied with one, of course) - the function always returns a "valid" lvalue because it enforces being called with an lvalue.
However in C++11 there is now a way to specify that a member function can only be called on lvalues, so you could achieve the same goal by writing the member function:
Test &operator=(Test obj2) &
// ^^^
Now the above code with dangling reference will fail to compile.
NB. operator=
should take the right-hand-side by either value or const reference. Taking by value is useful when implementing the copy and swap idiom, a technique for easily writing safe (but not necessarily the fastest) copy-assignment and move-assignment operators.
Why friend function can't be used for overloading assignment operator?
Short answer: Just because.
Somewhat longer answer: That's the way the syntax was fixed. A few operators have to be member functions. The assignment operator is one of the,
operator=
is a special member function that the compiler will provide if you don't declare it yourself. Because of this special status of operator=
it makes sense ro require it to be a member function, so there is no possibility of there being both a compiler-generated member operator=
and a user-declared friend operator=
and no possibility of choosing between the two.
$13.5.3 - "An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user (12.8), a base class assignment operator is always hidden by the copy assignment operator of the derived class."
Because there are some operators which MUST be members. These operators are:
operator[]
operator=
operator()
operator->
and type conversion operators, like operator int
.
Although one might be able to explain why exactly operator = must be a member, their argument cannot apply to others in the list, which makes me believe that the answer to "Why" is "Just because".
HTH
The intention of operator=
is an assignment operation to the current object. Then the LHS, or lvalue, is an object of the same type.
Consider a case where the LHS is an integer or some other type. That is a case handled by operator int()
or a corresponding operator T()
function. Hence the type of the LHS is already defined, but a non-member operator=
function could violate this.
Hence it is avoided.