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

为什么复制赋值运算符必须返回引用/ 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;

}


侃侃无极
浏览 761回答 3
3回答

墨色风雨

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

白衣染霜花

稍微澄清为什么最好通过引用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!总而言之,通过价值回归没有任何好处,但要失去很多。

慕姐8265434

当你重载时operator=,你可以写它来返回你想要的任何类型。如果你想要足够严重,你可以重载X::operator=以返回(例如)一些完全不同的类的实例Y或Z。但这通常是非常不可取的。特别是,您通常希望operator=像C一样支持链接。例如:int&nbsp;x,&nbsp;y,&nbsp;z;x&nbsp;=&nbsp;y&nbsp;=&nbsp;z&nbsp;=&nbsp;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&nbsp;two&nbsp;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&nbsp;entirely销毁。对于小向量,动态分配的时间可能比复制元素的时间高很多倍。唯一的另一个选项(在C ++ 11中添加)将返回一个右值引用。这很容易导致意想不到的结果 - 链接的任务a=b=c;可能会破坏内容b和/或c,这将是非常意外的。这使得返回正常引用(不是对const的引用,也不是rvalue引用)作为(合理地)可靠地产生大多数人通常想要的唯一选项。
打开App,查看更多内容
随时随地看视频慕课网APP