[問題] rvalue reference的討論

作者: w0005151 (藍廳)   2016-10-09 18:12:14
先說說我對rvalue reference的理解
假設有一個class myClass內包含指向heap記憶體的指標變數
在實作以myClass為引數建構子的時候
可以實作出引數lvalue及rvalue reference的版本
我看的書是分別稱作copy建構子跟move建構子
lvalue的版本代表引數不是一個暫時物件,之後還有可能會使用
因此新的物件必須要new出新的記憶體,再讓記憶體內容與作為引數的物件一致
rvalue的版本代表引數是一個暫時物件,在建構子結束後就會解構掉
因此可以讓新物件的指標直接與這個暫時物件的指標指向同個位置,免去new的動作
再讓暫時物件的指標指向NULL以免呼叫解構子時將塊記憶體delete掉
同樣的道理也可以用在operator=上
現在有o1,o2,o3三個myClass的實例
若myClass也有多載operator+
o1=o2+o3;
這時o1.operator=()會呼叫rvalue的版本,因為o2.operator+(o3)是一個暫時物件
而operator+()因為回傳的是一個暫時物件,回傳後就會刪除
所以回傳型態必須是myClass,不能是myClass&
這時候就會用到建構子將o2.operator+(o3)複製後再傳入o1.operator=()
但這次的建構子卻是呼叫lvalue的版本的copy建構子
這邊的原因我就不太理解,從書上看到是因為在o2.operator+(o3)中
這個回傳的暫時物件是有名字的(假設他叫result)
所以會被視作lvalue而呼叫lvalue的copy建構子
若希望能呼叫move建構子,則應該在return時使用std::move(result)
請問各位前輩我這樣的理解正確嗎?
另外有一個問題請教,通常operator+() operator-()因回傳的變數是區域變數
這些運算子會回傳一個新的物件而不是區域變數reference
而operator=() 則因為結果不是個區域變數而可以回傳lvalue reference
那又什麼情況我們會回傳rvalue reference嗎?
不好意思再補充個問題
在java中若我有兩個reference a,b
我可以用a=b讓a指向與b相同的物件
但在C++中a=b卻是會呼叫a指向的物件的operator=()
a實際上還是指向原來的物件(用取址運算子就可發現)
那有辦法讓a指向別的物件嗎?
作者: pttworld (批踢踢世界)   2016-10-09 18:27:00
精華區資料多,z-5。
作者: Caesar08 (Caesar)   2016-10-09 20:10:00
板上有很多文章,你應該先看一下。另外,你現在用的move就會return rvalue reference
作者: steve1012 (steve)   2016-10-09 22:50:00
rvalue跟是不是暫時物件不是這直接關聯的他的意思是 這塊記憶我可以直接拿來用 所以我用它來con
作者: firose (guest也是也是也是也是也)   2016-10-10 07:47:00
印象最深刻的還是 local 被傳回會被視為右值 (C++14)

Links booklink

Contact Us: admin [ a t ] ucptt.com