推 littleshan:其實到了 C++11 後要回傳 non-const object 12/14 14:09
→ littleshan:否則會無法利用到 move semantics 12/14 14:09
→ Feis:是, 但要幫 operator= 加 & 避免這問題 12/14 14:34
提到這個我想順便請教一下我對 C++11 的理解.
[前情提要]
原本的 operator+ 函式:
MyString operator+(const MyString &lhs, const MyString &rhs);
會造成:
MyString s1, s2, s3;
s1 + s2 = s3;
這樣的寫法是合法的.
但是運算子多載通常是希望讓自訂型態可以跟內建型態具有一樣的使用方式.
換句話說既然像下面這樣對整數的使用方法不行, 那我們也不應該讓自訂型態可以使用會比較好:
int i1, i2, i3;
i1 + i2 = i3;
[C++98 解決方法]
因此為了讓 s1 + s2 = s3 的寫法不合法,
C++98 的傳統解決方法是讓 operator+ 回傳 const 物件:
const MyString operator+(const MyString &lhs, const MyString &rhs);
因為 s1 + s2 的結果是 const 物件, 所以無法呼叫 operator= 這種 non-const 的成員函式.
我們利用回傳 const 物件的技巧間接解決這個問題.
但是這解決方法不只是讓 s1 + s2 = s3 不合法,
而是讓 operator+ 回傳的物件不能呼叫任何的 non-const 成員函式.
原本只是要讓 operator+ 回傳的物件不能呼叫 operator=,
卻因此讓任何的 non-const 成員函式都不能被呼叫.
而另外一個問題是在 C++11 裡面可以提供移動語意 (move) 的運算來增進效率.
卻因為回傳值是 const 物件而只能使用複製語意 (copy) .
[C++11 解決方法]
C++11 提供了 ref-qualifier 讓我們可以跟 const 一樣, 替每個成員函式單獨指定 ref-qualifier.
例如原本的 operator= (以 copy assignment 為例) :
class MyString {
public:
auto operator=(const MyString &rhs) noexcept -> MyString & = default;
};
可以加上一個 ref-qualifier (&) 而改成:
class MyString {
public:
auto operator=(const MyString &rhs) & noexcept -> MyString & = default;
};
這樣就可以讓 s1 + s2 = s3 不合法, 而不用將 operator+ 的回傳值設為 const 物件.
因為這裡的 & 使用方法跟 const 相似會強制這成員函式要用 l-value 的物件才可以呼叫.
這樣的解決方法更直接的規範 operator= 的使用.
總言之, 利用 ref-qualifier 可以得到:
1. 只限制 operator= 要被 l-value 的物件呼叫, 而不是限制所有的成員函式都這樣.
2. 因為 operator+ 回傳值可以是 non-const 的物件而因此得到移動語意的好處.
以上是我對 C++11 的認知, 不確定是否正確?
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.29.148
※ 編輯: Feis 來自: 140.112.29.148 (12/15 15:01)
推 littleshan:老大說的應該沒錯 (其實我也是現在才知道ref qualifier 12/16 21:17