为了账号安全,请及时绑定邮箱和手机立即绑定

为什么复制赋值运算符必须返回引用/ const引用?

为什么复制赋值运算符必须返回引用/ const引用?

C++
侃侃无极 2019-07-30 14:57:40
为什么复制赋值运算符必须返回引用/ const引用?在C ++中,我不清楚从复制赋值运算符返回引用的概念。为什么复制赋值运算符不能返回新对象的副本?另外,如果我上课A,还有以下内容:A a1(param);A a2 = a1;A a3;a3 = a2; //<--- this is the problematic line的operator=定义如下:A A::operator=(const A& a){    if (this == &a)    {        return *this;    }    param = a.param;    return *this;}
查看完整描述

3 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

严格地说,复制赋值运算符的结果不需要返回引用,但是为了模仿C ++编译器使用的默认行为,它应该返回对分配给的对象的非const引用(隐式生成的副本)赋值运算符将返回非const引用 - C ++ 03:12.8 / 10)。我已经看到了一些void从复制赋值重载返回的代码,我不记得何时引起严重问题。返回void将阻止用户进行“分配链接”(a = b = c;例如,将阻止在测试表达式中使用赋值结果。虽然这种代码绝不是闻所未闻,但我也认为它并不常见 - 特别是对于非原始类型(除非类的接口打算进行这类测试,例如iostreams)。

我不是建议你这样做,只是指出它是允许的,它似乎并没有引起很多问题。


查看完整回答
反对 回复 2019-07-30
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

稍微澄清为什么最好通过引用operator=返回以及按值返回---因为a = b = c如果返回值,链将正常工作。

如果您返回参考,则完成最少的工作。来自一个对象的值将复制到另一个对象。

但是,如果按值返回operator=,则会调用构造函数和析构函数每次调用赋值运算符!!

所以,给定:

A& operator=(const A& rhs) { /* ... */ };

然后,

a = b = c; // calls assignment operator above twice. Nice and simple.

但,

A operator=(const A& rhs) { /* ... */ };a = b = c; // calls assignment operator twice, calls copy constructor twice, calls destructor type to delete the temporary values! Very wasteful and nothing gained!

总而言之,通过价值回归没有任何好处,但要失去很多。


查看完整回答
反对 回复 2019-07-30
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

当你重载时operator=,你可以写它来返回你想要的任何类型。如果你想要足够严重,你可以重载X::operator=以返回(例如)一些完全不同的类的实例YZ。但这通常是非常不可取的。

特别是,您通常希望operator=像C一样支持链接。例如:

int x, y, z;x = y = z = 0;

在这种情况下,您通常希望返回所分配类型的左值或右值。这只留下了是否返回对X的引用,对X的const引用或X(按值)的问题。

将const引用返回到X通常是一个糟糕的想法。特别是,允许const引用绑定到临时对象。临时的生命周期延长到它所绑定的引用的生命周期 - 但不会递归到可能分配给它的任何生命周期。这使得返回悬空引用变得容易 - const引用绑定到临时对象。该对象的生命周期延长到引用的生命周期(在函数结束时结束)。到函数返回时,引用和临时的生命周期已经结束,因此分配的是悬空引用。

当然,返回非const引用并不能提供完全的保护,但至少会让你更加努力。您仍然可以(例如)定义一些本地,并返回对它的引用(但大多数编译器可以并且也将对此发出警告)。

返回值而不是引用具有理论和实际问题。在理论方面,=在这种情况下,通常意味着它意味着什么。特别是,在赋值通常意味着“获取此现有源并将其值分配给此现有目标”时,它开始意味着更像“获取此现有源,创建它的副本,并将该值分配给此现有目标。 “

From a practical viewpoint, especially before rvalue references were invented, that could have a significant impact on performance--creating an entire new object in the course of copying A to B was unexpected and often quite slow. If, for example, I had a small vector, and assigned it to a larger vector, I'd expect that to take, at most, time to copy elements of the small vector plus a (little) fixed overhead to adjust the size of the destination vector. If that instead involved two copies, one from source to temp, another from temp to destination, and (worse) a dynamic allocation for the temporary vector, my expectation about the complexity of the operation would be entirely销毁。对于小向量,动态分配的时间可能比复制元素的时间高很多倍。

唯一的另一个选项(在C ++ 11中添加)将返回一个右值引用。这很容易导致意想不到的结果 - 链接的任务a=b=c;可能会破坏内容b和/或c,这将是非常意外的。

这使得返回正常引用(不是对const的引用,也不是rvalue引用)作为(合理地)可靠地产生大多数人通常想要的唯一选项。


查看完整回答
反对 回复 2019-07-30
  • 3 回答
  • 0 关注
  • 760 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信