簡體   English   中英

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_i2
  • temp1.operator++(int) - 將temp1.m_i設置為3 ,並返回mi3 temp2
  • temp2.operator++() - 將temp2.m_i設置為4並返回對temp2的引用。

注意。 我的回答只談到重載運算符是一個成員函數。 也可以將++ (兩種形式)重載為非成員。 在這種情況下,行為將與我的描述保持一致,但“以函數調用表示法編寫”表達式將采用不同的語法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM