C++中operator+=与前置operator++返回引用的原因解析
为什么
operator+=和前置operator++要返回引用? 嘿,这个问题问得特别到位——刚上手C++运算符重载的小伙伴几乎都会纠结这个点。咱们结合内置类型的行为和自定义类型的语义来拆解:
先看fraction& operator+=(fraction);
咱们先回忆下内置类型的+=是怎么用的:
int a = 5; (a += 3) += 2; // 合法!最终a的值是10
这段代码能跑通,是因为a +=3返回的是a本身的引用,所以后续的+=2是直接在a的基础上继续修改。
如果你的operator+=返回的是值而非引用:
- 首先,
(a += b)会返回一个临时的fraction对象,再对这个临时对象做+=操作,修改的只是临时对象,原对象a不会被第二次修改,完全违背了用户对+=的直觉预期。 - 其次,返回值会触发拷贝构造函数,产生不必要的对象拷贝,拖慢程序性能;而返回引用只是返回原对象的别名,没有额外开销。
- 最重要的是:自定义类型的运算符重载要尽量和内置类型行为一致,这样别人读你的代码时不用额外记特殊规则,可读性拉满。
再看fraction& operator++();(前置++)
前置++的语义是「先自增,再返回自增后的对象」,同样看内置类型的例子:
int a = 5; ++(++a); // 合法!最终a的值是7
要是前置++返回的是值:
- 内层
++a会返回一个自增后的副本,外层++只会修改这个副本,原对象a只会被自增一次,完全不符合前置++的语义。 - 同样的,返回引用能避免拷贝,提升效率,同时和内置类型的链式调用行为保持一致。
这里可以和你的代码里的后置对比一下:fraction operator++(int);为什么返回值?因为后置的语义是「先返回当前对象的副本,再自增原对象」,所以必须返回临时副本——要是返回引用,拿到的就是已经自增后的对象,完全违背了后置++的“先取值后自增”的逻辑。
举个实际的代码例子
假设你的operator+=返回值:
fraction a(1, 2), b(1, 3); (a += b) += b; a.print(); // 结果只会是1/2 + 1/3 = 5/6,而不是5/6 +1/3=7/6
但如果返回引用,a会被连续加两次b,结果就是符合预期的7/6,和内置类型的表现一模一样。
内容的提问来源于stack exchange,提问作者Jack Internacional
相关产品推荐
相关产品推荐

