亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么復制賦值運算符必須返回引用/ 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 關注
  • 789 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號