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

来源:互联网 发布:牛牛开挂软件 编辑:程序博客网 时间:2024/06/11 01:23


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的成员变量xy的值赋值成l_myStruct_ref对应的成员变量值。接下来虽然局部变量l_myStruct_ref被销毁,但是myStruct3的值却保留了下来,所以myStruct3xy的值依然是34

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的成员变量值依然是34,如图6所示。但是,该地址已经被标记为可修改,之后再执行其他代码时,这个地址可能就会被修改为其他值,如图7所示。


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

 

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

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

原创粉丝点击