函数的返回值

一、缺省情况下,函数的返回值是按值传递的

这意味着得到控制权的函数将接收返回语句中指定的表达式的拷贝,例如:            

Matrix grow( Matrix* p ) { 
    Matrix val; 
 
     // ... 
     return val; 

grow()把存储在 val 中的值的拷贝返回到调用函数,但调用函数不能用任何方式修改val 。

 

二、该缺省行为可以被改变,一个函数可以被声明为返回一个指针或一个引用

当函数返回一个引用时,调用函数接收 val 的左值,即调用函数可以修改 val 或取它的地址。grow()可以如下声明返回一个引用:  
Matrix& grow( Matrix* p ) { 
Matrix *res; 
 
// 在动态存储中分配一个更大的 Matrix 
// res 是指向新 Matrix 的指针 
// 将*p 内容复制到*res 
return *res; 

如果返回值是一个大型类对象,用引用或指针返回类型比按值返回类对象效率要高得多,在某些情况下编译器自动将按值返回转换到按引用返回,该优化被称为命名返回值优化( named return value optimization )。

 

当声明一个返回引用的函数时,程序员应当知道下面两个易犯的错误:  

1.  返回一个指向局部对象的引用 局部对象的生命期随函数的结束而结束,在函数结束后,该引用变成未定义内存的别名,例如:
// 问题: 返回一个指向局部对象的引用 
Matrix& add( Matrix &m1, Matrix &m2 ) 

Matrix result; 
 
if ( m1.isZero() ) 
  return m2; 
if ( m2.isZero() ) 
  return m1; 
 
// 将两个 Matrix 对象的内容相加 
// 喔! 返回之后 结果指向一个有问题的位置 
return result; 
}
 
在这种情况下,返回类型应该被声明为非引用类型,然后再在局部对象的生前拷贝局部变量  
Matrix add( ... 

2.  函数返回一个左值 对返回值的任何修改都将改变被返回的实际对象,例:
#include <vector> 
 
int &get_val( vector<int> &vi, int ix ) { 
return vi[ix]; 

 
int ai[4] = { 0, 1, 2, 3 }; 
 
vector<int> vec( ai, ai+4 );  // 将 ai 的 4 个元素复制到 vec

int main() { 
// 将 vec[0] 增加到 1 
get_val( vec,0 )++; 
 
// ... 
}


为防止对引用返回值的无意修改,返回值应该被声明为const :
const int &get_val( ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值