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. 这个有机会再来讨论 :-) --
QR Code



※ 发信站: 批踢踢实业坊(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灯, 水草

请输入看板名称,例如:Soft_Job站内搜寻

TOP