处理赋值运算符重载;您可以重新分配引用吗?
dealing with assignment operator overloads; can you re-assign a reference?
如果你的类有一个引用变量,那么需要编写重载赋值运算符。
我的印象是,您只能在实例化时设置一次引用,因此不能执行以下操作:
MyClass& MyClass::operator=(const MyClass& rhs)
{
if (&rhs != this)
{
myReference = rhs.myReference;
}
return *this;
}
你如何解决这个问题?
编辑 - 好的,所以我被告知你不能在带有引用的类上使用赋值运算符,很好。但是为什么视觉工作室让我这样做呢?程序运行和一切。
不可以,您不能重新拔插参考。
考虑:
int a = 42, b = 43;
int &ar = a;
ar = b;
编译器如何知道您正在尝试重新拔插ar
以引用b
,而不是将a
的值设置为43
?
您可以使用指针而不是引用来解决此"问题"。
编辑:根据您的编辑,
好的,所以我被告知您不能在具有 参考,很好。但是为什么视觉工作室让我这样做呢?这 程序运行和一切。
你结论的前提是错误的。 可以在包含引用的类上使用赋值运算符。 您不能做的是重新拔插参考。 如上面的代码所示,如果您尝试使用 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_
所指的内容。 相反,它会在Foo
本身上调用operator=
。 运行上面的代码,您将看到bar2
中Foo
的地址永远不会更改。 如果可以重新拔插引用,它就会改变。
您可以使用使用引用的类创建赋值运算符,但以下行:
myReference = rhs.myReference;
不重新指派引用。 如果重新分配引用所引用的内容。 因此,在该赋值之后,myReference 和 rhs.myReference 现在不再引用同一个对象。 但是他们所指的事物现在具有等效的值(或该类型的任何赋值(。
如果需要可重新分配的引用,请使用指针。 这就是他们的目的。 事实上,在现代C++中,这几乎是原始指针的唯一用途。 如果你引用的对象是动态分配的,那么你应该把它放在一个shared_ptr
中,并使myReference成为另一个shared_ptr
,或者一个weak_ptr
。
用两个词来说 - 你不能。引用具有实际对象的语义,因此赋值运算符实际上将调用基础对象的赋值,而不是引用本身。
引用不能反弹。 (好吧,放置new
可以,但不要那样做!
但是代码是合法的,即使它没有做你认为它做的事情。 它不是重新绑定或重新分配引用,而是分配给引用对象(引用的目标(。
您的代码按编写的方式工作,但是您不会重新分配引用。
myReference = rhs.myReference;
将 rhs.myReference 引用的对象分配给 myReference。因此,假设赋值之前&myReference != &(rhs.myReference)
为真,则赋值后仍为真,但是这些地址上的对象将包含相同的值(因此myReference == rhs.myReference
如果operator==
是为类型定义的并且以非意外的方式工作(。重新分配引用(这是不可能的(意味着在分配之后&myReference == &(rhs.myReference)
为真。所以真正的问题是你想做什么:你是想将rhs.myReference
引用的对象复制到this->myReference
引用的对象中(在这种情况下,你的代码很好(,还是想this->myReference
引用与rhs.myReference
相同的对象(这在引用中是不可能的, 所以你需要使用指针(。
- 对具有动态分配的内存和析构函数的类对象的引用
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 我如何通过引用将 c++ 字符串分配给另一个字符串
- 将引用分配给局部变量,如果局部变量超出范围,它会超出范围吗?
- 如何在构造函数中构造对象并分配引用
- C++中的可重新分配引用
- 如何分配引用链的末端
- c++ 在 if 语句中分配引用变量
- 为什么不能重新分配引用的目标对象?
- 阻止重新分配引用
- C++ 从传入的引用变量中分配引用变量
- C++可以重新分配引用
- 重新分配C++引用变量
- 有条件地分配引用
- 我们可以在C++中重新分配引用吗
- C++在为指针分配引用时获取临时错误的地址
- 为什么可以在 for 语句中重新分配引用常量
- 如何(优雅地)根据字符别名分配引用成员
- 处理赋值运算符重载;您可以重新分配引用吗?
- 对左值和右值的可分配引用