当您重载时operator=
,您可以编写它以返回所需的任何类型。如果您想做的足够糟糕,则可以重载X::operator=
以返回(例如)某些完全不同的类Y
或的实例Z
。但是,这通常是非常不可取的。
特别是,您通常希望operator=
像C一样支持链接。例如:
int x, y, z;
x = y = z = 0;
在这种情况下,通常需要返回分配给该类型的左值或右值。剩下的问题是是否返回对X的引用,对X的const引用或X(按值)。
将const引用返回给X通常不是一个好主意。特别是,允许const引用绑定到临时对象。临时对象的生存期延长到其绑定的引用的生存期,但不递归地扩展到可能分配给它的任何对象的生存期。这使得返回悬挂的引用变得很容易-const引用绑定到临时对象。该对象的生存期延长到引用的生存期(在函数末尾终止)。在函数返回时,引用和临时对象的生存期已经结束,因此分配的是悬空的引用。
当然,返回非const引用并不能完全避免这种情况,但是至少会使您更加努力。您仍然可以(例如)定义一些局部变量,并返回对它的引用(但是大多数编译器也可以并且也会对此发出警告)。
返回值而不是引用具有理论和实践问题。从理论上讲,=
在这种情况下,通常含义与含义之间存在基本的分离。特别是,在分配通常意味着“获取此现有资源并将其值分配给该现有目的地”的地方,它开始意味着更像“获取该现有资源,创建它的副本,并将该值分配给该现有目的地”。 ”
从实践的角度来看,尤其是在发明右值引用之前,这可能会对性能产生重大影响-在将A复制到B的过程中创建一个完整的新对象是意料之外的,而且通常很慢。例如,如果我有一个较小的向量,并将其分配给一个较大的向量,则我希望最多花费时间来复制该较小向量的元素,再加上(少量)固定开销来调整该向量的大小。目标向量。如果相反地涉及两份副本,一份从源到临时,另一份从临时到目的地,并且(更糟)为临时向量动态分配,我对操作复杂性的期望是完全是毁了。对于较小的向量,动态分配的时间可能很容易比复制元素的时间高很多倍。
唯一的其他选择(在C ++ 11中添加)是返回右值引用。这很容易导致意外的结果-像这样的链式分配a=b=c;
可能会破坏b
and / or的内容c
,这将是非常意外的。
这使得返回普通引用(不是对const的引用,也不是右值引用)作为唯一的选项(合理地)可靠地产生大多数人通常想要的东西。
A&
就像a=b
是一个左值表达式引用a
的情况下,a
和b
是整数。