You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中personType类返回引用的成员函数链式调用问题咨询

为什么返回引用和值类型会导致链式调用结果不同?

这问题的核心其实就是返回对象引用和返回对象拷贝的本质区别,咱们一步步把它讲透:

1. 原版本(返回引用)的链式调用逻辑

原函数声明是这样的:

personType& setLastName(string last);
personType& setFirstName(string first);

当你调用p1.setLastName("Brad")时,函数内部把p1的lastName改成"Brad",然后返回*this的引用——引用就像是原对象的“别名”,并不是新创建的对象。所以接下来的.setFirstName("Pitt"),其实是直接在原对象p1上修改它的firstName。

整个链式调用的过程等价于:

p1.setLastName("Brad"); // 直接改p1的lastName
p1.setFirstName("Pitt"); // 直接改p1的firstName

自然最后p1.print()会输出正确的“Brad Pitt”。

2. 修改后(返回值类型)的问题所在

当你把返回值改成personType值类型后,函数变成:

personType setLastName(string last) { 
    lastName=last; 
    return *this; 
}
personType setFirstName(string first) { 
    firstName=first; 
    return *this; 
}

这里的关键是:返回*this的时候,会创建一个原对象的拷贝副本,而不是指向原对象的引用。

那链式调用p1.setLastName("Brad").setFirstName("Pitt")的实际流程是:

  1. 调用p1.setLastName("Brad"):成功修改了p1的lastName为"Brad",然后返回一个p1的拷贝对象(咱们叫它tempObj)。
  2. 调用tempObj.setFirstName("Pitt"):修改的是这个临时拷贝对象tempObj的firstName,和原对象p1完全没关系!
  3. 临时对象tempObj在链式调用结束后就被销毁了,原对象p1的firstName还是初始的空值(或者默认构造的默认值)。

所以最后p1.print()只会输出"Brad",因为firstName根本没被修改过。

3. 为什么分两次调用就正常?

分两次调用的代码是:

p1.setLastName("Brad"); 
p1.setFirstName("Pitt");

这里每次调用都是直接作用在原对象p1上,虽然setLastName返回了拷贝,但我们没有使用这个返回值,所以修改的是p1本身;同理setFirstName也是直接修改p1的firstName,所以两次修改都生效,结果自然正确。

简单总结:返回引用时,链式调用的每一步都在操作同一个原对象;返回值类型时,链式调用的后续步骤操作的是前一步返回的临时拷贝,和原对象无关。

内容的提问来源于stack exchange,提问作者Terrence

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:56:03