Нет, вы не можете переустановить ссылку.
Рассмотрим:
int a = 42, b = 43;
int &ar = a;
ar = b;
Как компилятор может узнать, что вы пытаетесь переустановить ar
для ссылки на b
, а не установить значение из a
в 43
?
Вы решаете эту «проблему», используя указатель, а не ссылку.
РЕДАКТИРОВАТЬ: В соответствии с вашими правками,
ОК, поэтому мне сказали, что вы не можете использовать оператор присваивания в классе с
Ссылка, хорошо. Но тогда почему Visual Studio позволяет мне это делать?
программа запускается и все.
Предпосылка вашего заключения неверна. Вы можете использовать оператор присваивания для класса, который содержит ссылку. То, что вы не можете сделать, это переместить ссылку. Как показано в моем коде выше, если вы попытаетесь переназначить ссылку, используя ar = a;
, вы не будете переопределять то, к чему относится ar
, но измените значение того, к чему относится ar
.
Visual Studio "позволяет вам делать это" без труда. Это недоразумение - именно то, что позволяет вам делать Visual Studio. Это не позволяет вам переустановить ссылку. Это позволяет вам изменить значение референта. Вот пример, который, я надеюсь, прояснит, что это значит.
#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();
}
Приведенный выше код устанавливает 2 Foo
объекта (foo1
и foo2
) и создает 2 Bar
объектов, каждый из которых имеет ссылку на свой Foo
. Bar
имеет operator=
, который выполняет следующее:
foo_ = rhs.foo_;
Если бы C ++ позволил вам переназначить ссылки таким образом, foo_
теперь будет ссылаться на другой экземпляр Foo
. Но это не так. Это не меняет того, к чему относится foo_
. Вместо этого он вызывает operator=
на самом Foo
. Запустите приведенный выше код, и вы увидите, что адрес Foo
в bar2
никогда не меняется. Если бы вы могли изменить ссылки, это изменилось бы.