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")的实际流程是:
- 调用
p1.setLastName("Brad"):成功修改了p1的lastName为"Brad",然后返回一个p1的拷贝对象(咱们叫它tempObj)。 - 调用
tempObj.setFirstName("Pitt"):修改的是这个临时拷贝对象tempObj的firstName,和原对象p1完全没关系! - 临时对象tempObj在链式调用结束后就被销毁了,原对象p1的
firstName还是初始的空值(或者默认构造的默认值)。
所以最后p1.print()只会输出"Brad",因为firstName根本没被修改过。
3. 为什么分两次调用就正常?
分两次调用的代码是:
p1.setLastName("Brad"); p1.setFirstName("Pitt");
这里每次调用都是直接作用在原对象p1上,虽然setLastName返回了拷贝,但我们没有使用这个返回值,所以修改的是p1本身;同理setFirstName也是直接修改p1的firstName,所以两次修改都生效,结果自然正确。
简单总结:返回引用时,链式调用的每一步都在操作同一个原对象;返回值类型时,链式调用的后续步骤操作的是前一步返回的临时拷贝,和原对象无关。
内容的提问来源于stack exchange,提问作者Terrence
相关产品推荐
相关产品推荐

