为何函数参数(Myclass)可接收左/右值,但返回同类型仅能返回右值?
问题解析
为什么Myclass foo(Myclass)的返回值是右值?
当函数返回值类型是值类型(比如Myclass,而非引用)时,不管你返回的是局部变量还是临时构造的对象,最终返回的都是一个临时对象(纯右值,prvalue):
- 在
fooReturnsL中,return a;看起来是返回局部变量a,但实际上编译器会把a的值拷贝到函数返回值的临时存储区(即使触发NRVO优化省略拷贝,这个返回对象在语义上依然是临时的)。 - 在
fooReturnsR中,return Myclass{};直接构造临时对象返回,本质和上述情况一致。
C++的左值引用(Myclass&)只能绑定到有持久内存身份的左值(比如全局变量、局部变量var_Myclass),而临时对象是右值,无法被左值引用直接绑定。相反,右值引用(Myclass&&)专门用来绑定临时对象,还能延长它的生命周期,所以你代码里右值引用绑定的语句是合法的。
能否让Myclass fooReturnsL(Myclass b)返回左值?
不行——只要函数签名是Myclass fooReturnsL(Myclass b)(返回值类型是值类型),就不可能返回左值。但如果修改函数的返回类型为左值引用(Myclass&),就可以返回左值,前提是返回的引用指向的对象在函数结束后依然有效:
合法示例:返回静态/全局变量的引用
class Myclass {}; Myclass global_Myclass; // 全局对象,生命周期贯穿整个程序 Myclass& fooReturnsL(Myclass b) { static Myclass static_Myclass; // 静态局部变量,生命周期到程序结束 return static_Myclass; // 返回左值引用,对应左值 // 或者 return global_Myclass; } int main() { Myclass var_Myclass; Myclass& lref = fooReturnsL(var_Myclass); // 合法,绑定到左值 }
错误示例:返回局部变量的引用
绝对不能返回局部变量的引用,比如:
Myclass& badFoo(Myclass b) { Myclass a; return a; // 未定义行为!a是局部变量,函数结束后立即销毁,返回的引用是悬垂引用 }
这种代码编译可能通过,但运行时会导致不可预测的错误。
内容的提问来源于stack exchange,提问作者rand_program
相关产品推荐
相关产品推荐

