如果您的类有一个引用变量,那么需要编写重载的赋值运算符。
我的印象是你只能在实例化时设置一次引用,因此无法执行以下操作:
MyClass& MyClass::operator=(const MyClass& rhs)
{
if (&rhs != this)
{
myReference = rhs.myReference;
}
return *this;
}
你如何解决这个问题?
编辑 - 好的,所以我被告知你不能在带引用的类上使用赋值运算符,很好。但是为什么视觉工作室会让我这样做呢?程序运行和一切。
答案 0 :(得分:1)
不,你不能重新安排参考。
考虑:
int a = 42, b = 43;
int &ar = a;
ar = b;
编译器如何知道您尝试重置ar
以引用b
,而不是将a
的值设置为{{1} }}?
您可以使用指针而非参考来解决此“问题”。
编辑:根据你的编辑,
好的,所以我告诉你不能在带有a的类上使用赋值运算符 参考,很好。但是为什么视觉工作室会让我这样做呢?该 程序运行和一切。
你的结论的前提是错误的。 可以在包含引用的类上使用赋值运算符。你不能做的是重新安排参考。如上面的代码所示,如果您尝试使用43
重新分配引用,则不会重置ar = a;
引用的内容,而是更改ar
引用的值。< / p>
Visual Studio“让你做到了”,没有任何困难。误解正是Visual Studio允许您做的事情。它不会让你重新安置参考。它让你改变了反叛者的价值。这是一个例子,我希望能澄清这意味着什么。
ar
上面的代码建立了2个#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();
}
个对象(Foo
和foo1
)并创建了2个foo2
个对象,每个对象都引用了不同的Bar
}。 Foo
有Bar
,执行以下内容:
operator=
如果C ++允许您以这种方式重新设置引用,foo_ = rhs.foo_;
现在将引用foo_
的其他实例。但是,事实并非如此。这不会改变Foo
引用的内容。相反,它会在foo_
本身上调用operator=
。运行上面的代码,您会发现Foo
中Foo
的地址永远不会改变。如果您可以重新设置引用,它就会改变。
答案 1 :(得分:0)
您可以使用使用引用的类创建赋值运算符,但是这一行:
myReference = rhs.myReference;
不重新分配参考。如果重新分配引用引用的东西。因此,在该赋值之后,myReference和rhs.myReference现在不会引用同一个对象。但是他们现在提到的东西具有相同的值(或者对于那种类型的任何赋值意味着)。
如果需要可重新分配的引用,请使用指针。这就是他们的目的。事实上,在现代C ++中,这几乎是原始指针的唯一用途。如果您引用的对象是动态分配的,那么您应该将其放在shared_ptr
中,并将myReference设为另一个shared_ptr
或weak_ptr
。
答案 2 :(得分:0)
用两个词 - 你不能。引用具有实际对象的语义,因此赋值运算符实际上将调用底层对象的赋值而不是引用本身。
答案 3 :(得分:0)
参考不能反弹。 (好吧,放置new
可以,但不要这样做!)
但代码是合法的,即使它没有按照你的想法做到。它不是重新绑定或重新分配引用,而是分配给引用(引用的目标)。
答案 4 :(得分:0)
您的代码按照书面形式运行,但您不重新分配参考。
myReference = rhs.myReference;
将rhs.myReference引用的对象分配给myReference。因此,假设在赋值&myReference != &(rhs.myReference)
之前为真,它在赋值后仍然为真,但这些地址处的对象将包含相同的值(如果为myReference == rhs.myReference
定义了operator==
类型和工作在一个让我们说不成型的方式)。重新分配引用(这是不可能的)将意味着在赋值&myReference == &(rhs.myReference)
之后将是真的。所以真正的问题是你想要做什么:你想将rhs.myReference
引用的对象复制到this->myReference
引用的对象(在这种情况下你的代码没问题),或者你想要make this->myReference
引用与rhs.myReference
相同的对象(这对于引用是不可能的,因此您需要使用指针)。