C++函数返回值为局部变量


C++函数的返回值是局部变量时,该返回值可能是值类型、指针类型和引用类型。

以自定义类型MyStruct为例:

struct MyStruct
{
int x;
int y;
};

1 返回值是自定义结构的值类型

定义一个返回值为MyStruct的函数MyProc1()

MyStruct MyProc1()
{
MyStruct l_mystruct;
l_mystruct.x = 1;
l_mystruct.y = 2;
return l_mystruct;
}
MyProc1() 的返回值是局部变量 myStruct 。在 main() 函数中,调用该函数

MyStruct myStruct = MyProc1();
在《C++ 函数的返回值(上)》一文中提到使用临时对象( temporary object )来保存函数的返回值。函数的返回值用于初始化调用点的一个临时对象,该临时对象就是函数调用的结果。所以,当函数返回值是自定义的值类型时,即使函数的返回值是局部变量,其返回值也是有效值,如图 1 、图 2 所示。

 

1 函数返回值是自定义结构的值类型时的流程

 

2 myStruct的值

 

2 返回值是自定义结构的指针类型

定义一个返回值是MyStruct*的函数MyProc2()

MyStruct* MyProc2()
{
MyStruct* l_pMyStruct =new MyStruct();
l_pMyStruct->x = 1;
l_pMyStruct->y = 2;
return l_pMyStruct;
}
MyProc2() 中,通过 new 关键字在堆( heap )上分配了内存,并且将该内存的地址保存到局部变量 l_pMyStruct 中,对内存进行赋值之后,返回该内存的地址。

main()函数中,调用MyProc2()函数。

MyStruct* pMyStruct = MyProc2();
此时,pMyStruct 的值是 MyProc2() 中在堆上分配的内存地址。因为当函数 MyProc2() 结束后,保存堆内存地址的局部变量 l_pMyStruct 被销毁,而堆内存本身不会被销毁。如图 3 、图 4 所示。

 

3 MyProc2()函数返回值

 

4 pMyStruct指向的内存值

3 返回值是自定义结构的引用类型

当函数的返回值是自定义结构的引用类型时,可以将该值赋值给值类型,也可以复制给引用类型。定义一个返回值是MyStruct引用的函数MyProc3()

MyStruct& MyProc3()
{
MyStruct l_myStruct_ref;
l_myStruct_ref.x = 3;
l_myStruct_ref.y = 4;
return l_myStruct_ref;
}
在该函数中,返回的是局部变量l_myStruct_ref 的引用。

3.1 将返回值赋值给值类型

main()函数中,将MyProc3()函数的返回值赋值给MyStruct结构的对象。

MyStruct myStruct3 = MyProc3();
正如在1 返回值是自定义结构的值类型”中提到的,当函数返回时,使用临时对象来保存局部变量 l_myStruct_ref 的引用,之后将 myStruct3 的成员变量 x y 的值赋值成 l_myStruct_ref 对应的成员变量值。接下来虽然局部变量 l_myStruct_ref 被销毁,但是 myStruct3 的值却保留了下来,所以 myStruct3 x y 的值依然是 3 4

3.2 将返回值赋值给引用类型

main()函数中,将MyProc3()函数的返回值赋值给MyStruct结构的引用类型。

MyStruct& myStruct_ref = MyProc3();
当函数返回时,使用临时对象来保存局部变量l_myStruct_ref 的引用,而变量 myStruct_ref 中保存的是临时变量的引用,其实也就是局部变量 l_myStruct_ref 的引用,当局部变量 l_myStruct_ref 被销毁,则 myStruct_ref 中的值同时被销毁,如图 5 所示。

 

5 myStruct_refl_myStruct_ref的关系

从代码中也可以看出,当执行完如下代码后,

MyStruct& myStruct_ref = MyProc3();
虽然此时myStruct_ref 的成员变量值依然是 3 4 ,如图 6 所示。但是, 该地址已经被标记为可修改,之后再执行其他代码时,这个地址可能就会被修改为其他值 ,如图7 所示。


6 MyProc3()函数返回后的内存

 

7 执行了其它语句后的内存

所以,C++Primer5版中文版》中提到,不要返回局部对象的引用

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值