C++类成员函数返回自身引用与直接修改成员的差异及选型依据
两个成员函数的核心差异
二者反汇编结果高度相似的前提是你没有用到testfunction1的返回值,此时编译器会自动优化掉返回引用的相关逻辑,二者执行流程完全一致。核心差异只有一点:
testfunction1执行完成后会返回当前对象的左值引用,调用方可以直接使用这个返回的引用testfunction2没有返回值,调用完成后只能再通过原对象名操作实例
差异的具体体现就是testfunction1支持链式调用:
test obj; // 合法,连续两次自增x obj.testfunction1().testfunction1(); // 非法,void返回值不能继续调用成员函数 obj.testfunction2().testfunction2();
你也可以直接把testfunction1的调用结果作为引用参数传给其他函数,不需要额外单独写变量名。
返回自身引用的设计背景
这个设计从C++标准化初期就已经存在,最核心的目的就是支持链式调用语法:
- 最典型的应用就是标准库的IO流,
std::cout << "a" << "b" << "c"的语法就是依赖每个<<运算符返回std::ostream&实现的 - C++标准也明确要求赋值运算符、
+=/-=这类复合赋值运算符必须返回自身引用,用来支持a = b = c、a += b += c这类链式赋值写法
后续这个设计也被广泛用到了建造者模式、流式API等设计场景里,用来简化连续调用的代码写法。
二者适用场景对比
选择返回自身引用的场景
- 你需要给接口提供链式调用能力,比如建造者模式的配置接口、流式操作接口
- 实现赋值、复合赋值、流运算符等有明确规范要求返回自身引用的运算符重载
- 有业务场景需要调用方直接拿到修改后的对象引用,不需要再单独传递原对象
选择void返回的场景
- 接口语义本身就是“执行一个独立操作,没有需要返回的结果”,用void更能体现接口设计意图,避免调用方误用返回值
- 对外暴露的公共API不需要链式调用能力,且你不希望调用方拿到对象引用后做额外的修改,减少接口误用风险
- 极致性能敏感的高频调用场景,此时void返回可以完全避免任何和返回值相关的冗余操作(绝大多数场景下性能差异可以忽略)
关于是否优先选择返回引用的判断
这个判断是错误的,不存在“优先选返回引用”的通用规则,完全取决于你的接口设计需求:
如果你的接口没有链式调用的需求,用void反而更清晰,相当于明确告诉调用方“这个函数没有可使用的返回结果”,后续你要修改接口实现的时候也不会有返回值相关的兼容性问题。只有当你明确需要返回引用带来的能力时,才应该选择这种设计。
内容的提问来源于stack exchange,提问作者james ray
相关产品推荐
相关产品推荐

