一、缺省情况下,函数的返回值是按值传递的
这意味着得到控制权的函数将接收返回语句中指定的表达式的拷贝,例如:
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( ... 
                    
                
                
            
        
浙公网安备 33010602011771号