Why do reference type members cause implicitly-declared copy assignment operator to be deleted
References are bound to an object when they are initialized and can never be altered after that, everything else you do to them affects the object they are bound to, not the reference itself.
So a reference member is set during construction, and never altered. Since the purpose of an assignment operator is to alter members after construction, it doesn't make sense to generate an implicit assignment operator when one of the member can never be altered. The compiler refuses to try and guess what you want it to do and forces you to provide your own assignment operator with the semantics you want.
Do I need to do anything in my operator= such as explicitly declare return *this or will the compiler (g++) handle this for me?
You absolutely definitely 100% need to return *this;
The only time you don't need an explicit return in C++ is if your function returns void
or in main()
(where there is an implicit return 0;
if you reach the end of the function) or in unusual cases such as functions that never return (either looping forever or throwing an exception).
Do I have to do anything special with the reference member?
It depends what semantics you expect assignment of your type to have.
If you don't want it to change the object the reference is bound to, fine, do nothing with it.
If you want assignment to alter the object the reference is bound to, you need to do that.
If you want the reference to be re-bound to a different object, you're out of luck, C++ doesn't allow that.
A reference cannot be changed. The object referenced by the reference can be changed, but the reference itself cannot.
Consider
struct A {
int &r;
A(int &r_) : r(r_) { }
};
int main() {
int i, j;
A a1(i), a2(j);
a1 = a2;
}
There is nothing you could possibly do in any custom operator=
implementation that would make a1.r
refer to j
, and that's why no operator=
gets created or should be created on your behalf.
If you have a situation in which it's okay for operator=
not to change that reference, then you can define your own.
If you have a situation where you need operator=
to change a reference, your class shouldn't be using a reference. A pointer might be more appropriate.