C++运算符重载中何时在operator前加&引用符号,原因是什么
C++运算符重载返回引用的适用规则
你示例中两个运算符的差异原因
operator<<返回引用的原因
std::ostream是不可拷贝类型,C++标准库直接删除了流对象的拷贝构造和拷贝赋值函数,根本无法按值返回,只能返回引用才能通过编译。- 符合链式调用的原生语义:你写的
std::cout << money1 << std::endl;本质等价于(operator<<(std::cout, money1)) << std::endl;,第一次调用返回std::cout的引用,才能接着调用后续的<<输出endl。如果按值返回,哪怕能编译,链式调用操作的也是拷贝出来的临时流对象,不会对原cout生效,输出逻辑完全错误。
operator==不返回引用的原因
- 相等运算符的语义是返回两个对象的比较结果,是
bool类型的临时值,基础类型拷贝成本极低,返回引用没有任何收益。 - 如果强行返回
bool&会产生悬垂引用问题:函数内的临时bool值会在函数执行结束后销毁,返回的引用会指向无效内存,属于未定义行为,会直接导致程序运行异常。
通用判断规则
是否返回引用的核心判断标准有两个:
- 你要返回的对象,在函数执行结束后是否依然存在,不会被销毁
- 返回引用是否符合该运算符的原生语义
常见需要返回引用的场景
- 赋值类运算符:
operator=、operator+=、operator-=等复合赋值运算符,返回当前对象的引用,支持a = b = c这类链式赋值,符合内置类型的赋值语义。 - 流输入输出运算符:
operator<<、operator>>,流对象不可拷贝,必须返回引用支持链式调用。 - 下标访问运算符
operator[]:返回元素的引用,才能支持arr[2] = 10这类修改元素的操作,符合内置数组的下标使用逻辑。 - 解引用
operator*、箭头operator->、前置自增/自减operator++/operator--:都是对当前对象本身操作,对象在函数结束后依然有效,返回引用符合原生语义。
常见不需要返回引用的场景
- 比较类运算符:
operator==、operator!=、operator<等,返回的是bool类型临时结果,返回引用会产生悬垂引用。 - 算术类运算符:
operator+、operator-、operator*等,返回的是运算产生的新临时对象,函数结束后临时对象销毁,无法返回有效引用。 - 后置自增/自减
operator++(int)/operator--(int):返回的是修改前的对象临时拷贝,只能按值返回。 - 逻辑运算符
&&/||、取反运算符!等,返回的都是临时布尔值,不需要返回引用。
内容的提问来源于stack exchange,提问作者UUser196
相关产品推荐
相关产品推荐

