![](/img/trans.png)
[英]How to differentiate (when overloading) between prefix and postfix forms of operator++? (C++)
[英]How does a C++ compiler expand prefix and postfix operator++()?
考慮:
class Example
{
private:
int m_i;
public:
Example(int i) : m_i{i} {}
//Post-fix
Example operator++(int) {m_i++; return *this;}
//Pre-fix
Example& operator++() {m_i++; return *this;}
void print() const {std::cout << m_i << '\n'}
};
我正在試驗這個以確定編譯器如何擴展對前綴和后綴運算符的調用。
例如,當我寫這樣的東西時:
Example e = 1;
e++;
我預計它會擴展到“e.operator++(int)”之類的東西,或者更進一步,我預計
e++(2);
擴展為“e.operator++(2)”之類的東西,但我得到的是編譯器抱怨一些“不匹配調用'(示例)(int)'”。
接下來我很好奇“++e”如何神秘地擴展為“e.operator++()”,即返回引用的那個。
玩了更多,我最終得到:
Example e = 1;
++e++;
e.print();
其中打印了 2,然后:
Example e = 1;
(++e)++;
e.print();
其中打印了 3。
我知道 (++e) 返回對對象的引用,然后將其后遞增 1,所以這是有道理的。 我還懷疑“++e++”在這里給出了后綴運算符的優先級(正如我在另一篇文章中讀到的),所以這是增加后綴運算符返回的臨時變量。 這也有道理。 這讓我想知道表達式是如何
++++e
++e++++
++++e++
++++e++++
被擴展(它們都以預期的結果編譯和運行)。
所以真的,內部到底發生了什么,編譯器如何知道要調用哪個 operator++() ,以及這些表達式是如何擴展的(尤其是在前綴情況下)? “operator++(int)”中占位符變量的用途是什么?
“operator++(int)”中占位符變量的用途是什么?
因為++
運算符有兩個不同的功能:postfix-++ 和 prefix-++。 因此,在重載它時,必須有兩個不同的函數簽名。
編譯器如何知道調用哪個 operator++(),
當您的代碼使用前綴++
(例如: ++e;
)時,將調用帶有簽名operator++()
的函數。 當您的代碼使用 postfix- ++
(例如: e++
;) 時,會調用帶有簽名operator++(int)
的函數,並且編譯器將提供一個未指定的虛擬參數值。
從技術上講, operator++(int)
可以使用虛擬參數值。 你可以通過編寫e.operator++(5);
來傳遞你自己的值e.operator++(5);
而不是e++;
. 但這會被認為是糟糕的編碼風格——當重載運算符時,建議保留內置運算符的語義以避免混淆閱讀代碼的人。
請注意,您當前的 postfix- ++
實現不遵守此規則:正常語義是應返回先前的值; 但您的代碼返回更新后的值。
++e++++;
要解析此語句,您需要了解以下解析規則:
++ e ++ ++;
(而不是一些一元- +
運算符)。 查閱該表達式的表格會告訴您: ++(((e++)++))
。 使用我之前提到的擴展,這可以寫成函數調用符號:
((e.operator++(0)).operator++(0)).operator++();
在這種情況下,需要從左到右調用這些函數,因為在對調用它的表達式求值之前無法輸入成員函數。
所以,假設我們有Example e(1);
在此語句之前,以下函數調用按此順序發生:
e.operator++(int)
- 將e.m_i
設置為2
並返回一個臨時的(我將其稱為temp1
作為偽代碼),其中temp1.m_i
為2
。temp1.operator++(int)
- 將temp1.m_i
設置為3
,並返回mi
為3
temp2
temp2.operator++()
- 將temp2.m_i
設置為4
並返回對temp2
的引用。 注意。 我的回答只談到重載運算符是一個成員函數。 也可以將++
(兩種形式)重載為非成員。 在這種情況下,行為將與我的描述保持一致,但“以函數調用表示法編寫”表達式將采用不同的語法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.