Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why cannot a non-member function be used for overloading the assignment operator?

The assignment operator can be overloaded using a member function but not a non-member friend function:

class Test {     int a; public:     Test(int x)         :a(x)     {}     friend Test& operator=(Test &obj1, Test &obj2); };  Test& operator=(Test &obj1, Test &obj2)//Not implemented fully. just for test. {     return obj1; } 

It causes this error:

error C2801: 'operator =' must be a non-static member

Why cannot a friend function be used for overloading the assignment operator? The compiler is allowing to overload other operators such as += and -= using friend. What's the inherent problem/limitation in supporting operator=?

like image 635
bjskishore123 Avatar asked Oct 14 '10 13:10

bjskishore123


People also ask

Why can't we overload assignment operator using friend function?

As friend function is not a member of class, it does not require object for its invocation. Therefore the first argument of operator need not be object of the class for which operator is being overloaded. However at least one of the operands must be the object of the class for which operator is being overloaded.

Which operators Cannot be used for operator overloading?

Operators that cannot be overloaded in C++ For an example the sizeof operator returns the size of the object or datatype as an operand. This is evaluated by the compiler. It cannot be evaluated during runtime. So we cannot overload it.

Can you overload the assignment operator?

You can overload the assignment operator (=) just as you can other operators and it can be used to create an object just like the copy constructor. Following example explains how an assignment operator can be overloaded.

Which operator is required to be overloaded as member function only?

Explaination. Overloaded assignment operator does the job similar to copy constructor and is required to be overloaded as member function of the class.


1 Answers

Firstly, it should be noted that this has nothing to do with the operator being implemented as a friend specifically. It is really about implementing the copy-assignment as a member function or as a non-member (standalone) function. Whether that standalone function is going to be a friend or not is completely irrelevant: it might be, it might not be, depending on what it wants to access inside the class.

Now, the answer to this question is given in D&E book (The Design and Evolution of C++). The reason for this is that the compiler always declares/defines a member copy-assignment operator for the class (if you don't declare your own member copy-assignment operator).

If the language also allowed declaring copy-assignment operator as a standalone (non-member) function, you could end up with the following

// Class definition class SomeClass {   // No copy-assignment operator declared here   // so the compiler declares its own implicitly   ... };  SomeClass a, b;  void foo() {   a = b;   // The code here will use the compiler-declared copy-assignment for `SomeClass`   // because it doesn't know anything about any other copy-assignment operators }  // Your standalone assignment operator SomeClass& operator =(SomeClass& lhs, const SomeClass& rhs);  void bar() {   a = b;   // The code here will use your standalone copy-assigment for `SomeClass`   // and not the compiler-declared one  } 

As seen in the above example, the semantics of the copy-assignment would change in the middle of the translation unit - before the declaration of your standalone operator the compiler's version is used. After the declaration your version is used. The behavior of the program will change depending on where you put the declaration of your standalone copy-assignment operator.

This was considered unacceptably dangerous (and it is), so C++ doesn't allow copy-assignment operator to be declared as a standalone function.

It is true that in your particular example, which happens to use a friend function specifically, the operator is declared very early, inside the class definition (since that's how friends are declared). So, in your case the compiler will, of course, know about the existence of your operator right away. However, from the point of view of C++ language the general issue is not related to friend functions in any way. From the point of view of C++ language it is about member functions vs. non-member functions, and non-member overloading of copy-assignment is just prohibited entirely for the reasons described above.

like image 135
AnT Avatar answered Oct 13 '22 14:10

AnT