>operator= can only be a member function.
Correct.
>It is intimately connected to the object on the left side of the =.
Yes, but not so intimately (ie. constructor or destructor) that a non-member function is completely illogical. You could, if C++ allowed it, do this, and nobody would question how reasonable it is:
class C {
friend void operator= ( C& lhs, const C& rhs );
};
void operator= ( C& lhs, const C& rhs )
{
// Assign rhs to lhs
}
>If it was possible to define operator= globally, then you might attempt to redefine the built-in = sign
That's a different issue entirely. It's trivial for an implementation to allow a non-member operator= but disallow defining it on built-in types. The reason operator= is required to be a member is because operator= has default behavior. If you redefine it globally, there's a distinct threat of a = b meaning different things to different parts of the code. Consider this:
struct C {
// Default operator= (shallow copy)
char *p;
};
void foo ( C& c )
{
C scratch;
// Work with scratch
c = scratch;
}
void operator= ( C& lhs, const C& rhs )
{
// Assign rhs to lhs (deep copy)
}
void bar ( C& c )
{
C scratch;
// Work with scratch
c = scratch;
}
int main()
{
C test;
foo ( test );
bar ( test );
}
foo doesn't know that operator= was redefined because function declarations are positional. If you declare an overload after you use the function, the overload isn't recognized. So foo will use the default operator=, which performs a shallow copy and ends up aliasing the pointer in c with the transient pointer in scratch that will get destroyed when foo returns. Therefore you have a memory leak, data loss, *and* an unexpected pointer to freed memory, whereas bar has none of these problems because it uses the overloaded operator= and correctly performs a deep copy.