C_and_CPP 板


LINE

※ 引述《cplusplus (永夜)》之銘言: : ※ 引述《LPH66 (運命のルーレット廻して)》之銘言: : : 這表示前置++ 它是可以做為左值的(雖然好像沒什麼意義) : : 因此要回傳其參考 : 其實這是蠻有爭議性的,這邊只是因為前置++的特性是先運算完再傳回運算完的值 : 所以可以傳回物件本身,不過語意上來講,應該是要傳回他的值(r-value) : 就是 Object, 但是位了效率避免copy,就傳回參考 Object& : 但是傳回的"東西"又不該代表原本的物件本身以防被修改(r-value) : 所以也有很多是採用 const Object& : 因此傳回Object &有爭議,必須要看看你的OBJECT的特性來決定 : 如果像是表示value的class,最好可以遵循一般大眾的認知 : 因為像是 ++(++a) 這樣用上面的方式可行,但是概念上不與primitive type的行為不符 : 所以這有可討論的空間 : ps ++++a 在有的compiler可行 有的就不行 盡量別用吧 這裡是 C 和 C++ 不同的地方。assignment operation (包括 =, +=, -=, ...,還有這裡所討論的 prefix ++) 其傳回值, 在 C 是 rvalue, 而 C++ 是 lvalue. 對 C++ 來說,prefix ++ expression 是 lvalue, 而 postfix ++ 才和 C 一樣,是 rvalue. C++ 的 prefix ++ 以及其他的 assignment expression 是 lvalue 有什麼用處呢?可以用在函式的 call-by-reference 和 return by reference. (顯然這是 C 所沒有的),如: void f(int& n) { if (n == 1) n = 2; } //... int i = 0; f(++i); // i 先加1,然後以 lvalue 做為引數,呼叫完函式 i 就會變成 2 cout << i << endl; // 印出 2 int& g(int n = 0) { static int i = 0; return i += n; } //... cout << g(1) << endl; // 印出 1 g() += 2; // 可以從外面改變 g() 中 static int i 的值 cout << g() << endl; // 印出 3 以上是針對內建型別和內建 operator。至於 UDT(user-defined type) 和 user-defined overloaded operator 當然可以自己高興要傳回 rvalue 或 lvalue, 只是為了給使用者最小的意外,最好能仿照內建 operator 的行為, 以維持統一的程式風格。這樣一來,像是 function template 也能同時吃 內建型別和 UDT 做為其 reference-type argument 而不會發生不一致的情形: template <typename T> void foo(T& a) { /* ... */ } //... int x = 0; foo(++x); class C { /* 有定義 C& operator++(); */ }; C c; foo(++c); 至於 int a = 0; ++++a; 這種寫法,由於對 C 來說 ++a 是 rvalue 所以就不能在 rvalue 上再做 ++ 的動作,於是 ++++a 用 C compiler 來編,就不能通過(ill-formed)。但是 C++ 的話,由於 ++a 是 lvalue, 所以再做一次 ++ 的話,是可以通過編譯。只是 C++ 和 C 一樣,另外 有一條重要的規定,就是在一個 expression 中,不能對同一個 scalar object(不妨理解成原始型別的變數)所存的值修改超過一次以上。否則 結果就是 undefined behavior. undefined behavior 是很討厭的東西,標準並不要求編譯器一定 要對此發出任何警告或錯誤訊息,但是若編譯器編出的碼執行出 任何可怕的後果(包括引爆核彈),仍然不算違反標準。所以寫程式 的人自己要非常小心,即使能編,一時也能執行出某種好的結果, 只要標準說是 undefined behavior 的寫法就絕對不要去碰。 (以前討論過的 cout << i << ++i; 也是這一類) 所以 ++++a 雖然可通過 C++ 的編譯,但不應該這麼寫。 再來看 user-defined postfix operator++ 依照上述的理由, 固然也該和 built-in postfix ++ 一樣,傳回 rvalue, 但這 個 rvalue (假設 type 是 T) 究竟該用 T 就好,還是 const T。 像 Scott Meyers 和 Herb Sutter 都是用 const T, 不過也有 專家認為該用 T. 這個有機會再來討論 :-) --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.130.208.168
1F:推 UNARYvvv:推引爆核彈XDD 61.59.30.19 06/24
2F:推 cplusplus:大感激 原來我認知的一直是C的概念 @@ 140.115.205.46 06/24
3F:推 cplusplus:一直以為編譯器因實做方便 prefix才傳回lvalue 140.115.205.46 06/24
4F:推 FlyinDeath:這篇應該要M起來~ 218.160.84.199 06/24
5F:推 SHBK:趕快有新板主出來m這篇吧~ XD 218.163.120.36 06/25







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:e-shopping站內搜尋

TOP