No, you cannot re-seat a reference.
Consider:
int a = 42, b = 43;
int &ar = a;
ar = b;
How can the compiler know that you are trying to reseat ar
to refer to b
, and not set the value of a
to 43
?
You solve this "problem" by using a pointer, not a reference.
EDIT: Per your edit,
OK so I'm told you cannot use an assignment operator on a class with a
reference, fine. But then why does visual studio let me do it? The
program runs and everything.
The premise of your conclusion is wrong. You can use an assignment operator on a class which contains a reference. What you cannot do is re-seat a reference. As demonstrated in my code above, if you try to reassign a reference using ar = a;
you will not re-seat what ar
refers to, but change the value of what ar
refers to.
Visual Studio "lets you do it," without difficulty. The misunderstanding is exactly what Visual Studio is letting you do. It's not letting you re-seat the reference. It's letting you change the value of the referant. Here is an example that I hope will clarify what this means.
#include <iostream>
#include <string>
using namespace std;
class Foo
{
public:
void dump() const
{
cout << "Foo instance " << showbase << this << "\n";
}
};
class Bar
{
public:
Bar(Foo& foo) : foo_(foo) {}
Bar& operator=(const Bar& rhs)
{
foo_ = rhs.foo_;
return * this;
}
void dump() const
{
cout << showbase << "Bar instance " << this << "\t";
foo_.dump();
}
private:
Foo& foo_;
};
int main()
{
cout << "foo1: ";
Foo foo1;
foo1.dump();
cout << "foo2: ";
Foo foo2;
foo2.dump();
cout << "bar1 :";
Bar bar1(foo1);
bar1.dump();
cout << "bar2 :";
Bar bar2(foo2);
bar2.dump();
bar2 = bar1;
cout << "bar2 after assign :";
bar2.dump();
}
The code above establishes 2 Foo
objects (foo1
and foo2
) and creates 2 Bar
objects, each of which has a reference to a different Foo
. Bar
has an operator=
, which executes the following:
foo_ = rhs.foo_;
If C++ allowed you to re-seat references in this way, foo_
would now refer to a different instance of Foo
. But, it doesn't. This doesn't change what foo_
refers to. Instead, it calls operator=
on the Foo
itself. Run the above code and you'll see that the address of the Foo
in bar2
never changes. If you could re-seat references, it would change.