日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++之运算符重载(前置++和后置++)

發布時間:2025/3/17 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++之运算符重载(前置++和后置++) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天在閱讀《google c++ 編程風格》的文檔的時候,5.10. 前置自增和自減:有一句話引起了我的注意:

對于迭代器和其他模板對象使用前綴形式 (++i) 的自增, 自減運算符.,理由是 前置自增 (++i) 通常要比后置自增 (i++) 效率更高。于是我查了查前置++和后置++的區別。

注意:《more effective c++》條款8也專門敘述了問題。后來我發現,下面的文章基本就是它的翻版,哈哈

前置++和后置++的區別?

  • int?a?=?0;??
  • ++?a;???//前置++??
  • a++;????//后置++??

  • 《C專家編程》中有如下描述(P276,人民郵電出版社):

    ?

    ++a表示取a的地址,增加它的內容,然后把值放在寄存器中;

    a++表示取a的地址,把它的值裝入寄存器,然后增加內存中的a的值;

    ?

    另外,網上找了篇文章,通過從運算符重載的角度來探討他們的不同,如下:

    ?

    假設有一個類Age,描述年齡。該類重載了前置++和后置++兩個操作符,以實現對年齡的自增。

  • class?Age?????
  • {?????
  • public:?????
  • ????
  • ????Age&?operator++()?//前置++?????
  • ????{?????
  • ????????++i;?????
  • ????????return?*this;?????
  • ????}?????
  • ????
  • ????const?Age?operator++(int)?//后置++?????
  • ???{?????
  • ????????Age?tmp?=?*this;?????
  • ????????++(*this);??//利用前置++?????
  • ????????return?tmp;?????
  • ????}?????
  • ????
  • ????Age&?operator=(int?i)?//賦值操作?????
  • ????{?????
  • ????????this->i?=?i;?????
  • ????????return?*this;?????
  • ????}?????
  • ????
  • private:?????
  • ????int?i;?????
  • };? ??
  • 從上述代碼,我們可以看出前置++和后置++,有3點不同:

  • 返回類型不同
  • 形參不同
  • 代碼不同
  • 效率不同
  • 返回值類型的區別

    前置++的返回類型是Age&,后置++的返回類型const Age。這意味著,前置++返回的是左值,后置++返回的是右值。(關于左值和右值的討論很多,見本文下面)

    左值和右值,決定了前置++和后置++的用法。

  • int?main()?????
  • {?????
  • ????Age?a;?????
  • ????
  • ????(a++)++;??//編譯錯誤?????
  • ????++(a++);??//編譯錯誤?????
  • ????a++?=?1;???//編譯錯誤?????
  • ????(++a)++;??//OK?????
  • ????++(++a);??//OK?????
  • ????++a?=?1;???//OK?????
  • }? ??
  • ++的類型是const Age,自然不能對它進行前置++、后置++、賦值等操作。

    ++a的類型是Age&,當然可以對它進行前置++、后置++、賦值等操作

    ?

    a++的返回類型為什么要是const對象呢?

    有兩個原因:

  • 如果不是const對象,a(++)++這樣的表達式就可以通過編譯。但是,其效果卻違反了我們的直覺?。a其實只增加了1,因為第二次自增作用在一個臨時對象上。
  • 另外,對于內置類型,(i++)++這樣的表達式是不能通過編譯的。自定義類型的操作符重載,應該與內置類型保持行為一致?。
  • a++的返回類型如果改成非const對象,肯定能通過編譯,但是我們最好不要這樣做。

    ?

    ++a的返回類型為什么是引用呢?

    這樣做的原因應該就是:與內置類型的行為保持一致。前置++返回的總是被自增的對象本身。因此,++(++a)的效果就是a被自增兩次。

    ?

    形參的區別

    前置++沒有形參,而后置++有一個int形參,但是該形參也沒有被用到。很奇怪,難道有什么特殊的用意?

    其實也沒有特殊的用意,只是為了繞過語法的限制。

    ?

    前置++與后置++的操作符重載函數,函數原型必須不同。否則就違反了“重載函數必須擁有不同的函數原型”的語法規定。

    雖然前置++與后置++的返回類型不同,但是返回類型不屬于函數原型。為了繞過語法限制,只好給后置++增加了一個int形參。

    ?

    原因就是這么簡單,真的沒其他特殊用意。其實,給前置++增加形參也可以;增加一個double形參而不是int形參,也可以。只是,當時就這么決定了。

    ?

    代碼實現的區別

    前置++的實現比較簡單,自增之后,將*this返回即可。需要注意的是,一定要返回*this。

    后置++的實現稍微麻煩一些。因為要返回自增之前的對象,所以先將對象拷貝一份,再進行自增,最后返回那個拷貝。

    ?

    在Age的代碼中,后置++利用了前置++來實現自增。這樣做是為了避免“自增的代碼”重復。

    在本例中,自增的代碼很簡單,就是一行++i,沒有必要這樣做。但是在其它自增邏輯復雜的例子中,這么做還是很有必要的。

    ?

    效率的區別

    如果不需要返回自增之前的值,那么前置++和后置++的計算效果都一樣。但是,我們仍然應該優先使用前置++,尤其是對于用戶自定義類型的自增操作。

    前置++的效率更高,理由是:后置++會生成臨時對象。

    ?

    從Age的后置++的代碼實現也可以看出這一點。

  • const?Age?operator++(int)?//后置++?????
  • {?????
  • ????Age?tmp?=?*this;?????
  • ????++(*this);??//利用前置++?????
  • ????return?tmp;?????
  • }? ??
  • 很明顯,tmp是一個臨時對象,會造成一次構造函數和一次析構函數的額外開銷。雖然,編譯器在某些情況下可以優化掉這些開銷。但是,我們最好不要依賴編譯器的行為。


    所以,在非內置類型的時候,盡量使用前置++,因為效率高(后置自增,效率低)

    轉載于:https://www.cnblogs.com/cthon/p/9185263.html

    總結

    以上是生活随笔為你收集整理的C++之运算符重载(前置++和后置++)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。