Why Cannot a Non-Member Function Be Used for Overloading the Assignment Operator

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

Because the default operator= provided by the compiler (the memberwise copy one) would always take precedence. I.e. your friend operator= would never be called.

EDIT: This answer is answering the

Whats the inherent problem/limitation in supporting = operator ?

portion of the question. The other answers here quote the portion of the standard that says you can't do it, but this is most likely why that portion of the standard was written that way.

Overloading operator= as Non-Member

If your class doesn't have an assignment operator (as a member), the compiler generates one by default, just like it generates a copy constructor if you don't provide one.

Therefore it will be "angry" if you try to define a non-member assignment operator later. There will then be two!

Why must (), [], - , and = be overloaded only as member functions?

I think this is most likely why that portion of the standard was written that way.

but if it is not forbidden, the friend version would never be called, in my testing code ,when

 Complex operator+(const Complex &other);

is defined as private, the compiler would
give error message

‘Complex Complex::operator+(const Complex&)’ is private
Complex Complex::operator+(const Complex &other)

instead of using the friend version

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

Because the default operator= provided by the compiler (the memberwise copy one) would always take precedence. I.e. your friend operator= would never be called.

(If the assignment was performed inside a class method, because of the lookup rules, the member function (in this case generated by the compiler) would take precedence)

I try to using operator + for test. it prove the precedence

it outputs:

member function called
7+11i

testing code:

#include<iostream>
using namespace std;
class Complex
{
public:
Complex(int real, int imag);
Complex(void);
~Complex(void);

Complex &Add(const Complex &other);

void Display() const;

Complex operator+(const Complex &other);

friend Complex operator+(const Complex &c1, const Complex &c2);

private:
int real_;
int imag_;
};
Complex::Complex(int real, int imag): imag_(imag), real_(real)
{

}
Complex::Complex(void)
{
}

Complex::~Complex(void)
{
}

Complex &Complex::Add(const Complex &other)
{
real_ += other.real_;
imag_ += other.imag_;
return *this;
}

void Complex::Display() const
{
cout << real_ << "+" << imag_ << "i" << endl;
}

Complex Complex::operator+(const Complex &other)
{
int r = real_ + other.real_;
int i = imag_ + other.imag_;
std::cout << "member function called"<< std::endl;
return Complex(r, i);
}

Complex operator+(const Complex &c1, const Complex &c2)
{
int r = c1.real_ + c2.real_;
int i = c1.imag_ + c2.imag_;
std::cout << "friend function called"<<std::endl;
return Complex(r, i);
}

int main(void)
{
Complex c1(3, 5);
Complex c2(4, 6);

Complex c3 = c1 + c2;

c3.Display();

return 0;
}

Why is function overloading between member functions and non-member functions not allowed?

You're mostly asking why so rather than saying "because the language says so", lets show an example where your suggestion causes everything to fail.

Suppose I have a handy class in my github repo:

struct HandyClass {
void display(short c) {
std::cout << c;
}
void doStuff() {
display(3);
}
};

And then some other developer in a different github repro makes a handy set of display functions:

void display(double v) {
showWindowsPopup("Your score was %f", v);
}
void display(int v) {
showWindowsPopup("Your score was %d", v);
}

You download both repros, and suddenly, HandyClass doesn't work right anymore:

#include "displays.h"
#include "handyclass.h"

int main() {
HandyClass a;
a.doStuff(); //Why does this show a windows popup!?!?
}

Because you included the display headers first, then display(3) matched to ::display(int) instead of ::HandyClass::display(short), because 3 is an int. And much sadness occurs.

But with the official C++ lookup rules, this doesn't happen. Since my class has display functions, it will ignore functions outside the class, to prevent mistakes, so that HandyClass always does the same thing for everyone.

Overloading Operator = as a member function

The compiler generates a default copy assignment operator (operator=) for all classes that do not define their own. That means that a global overload won't be selected under any circumstances.



Related Topics



Leave a reply



Submit