C++函数返回引用、非引用以及临时变量的问题

C++中新增了引用类型,因此函数的返回值能够是引用类型。那么就会有人想问 返回引用类型与返回非引用类型有区别吗?ios

结论是显然的,并且有明显的区别。尤为初学者会很容易绕进去。让咱们先看四个函数原型。以int类型来举例安全

 (1) int fun(...)
函数

         {spa

     return ....//后面跟的是一个引用对象

         }教程

例如:int fun(int &a)内存

        {作用域

          return a; 
原型

        }                                                                                        
编译器

  (2)int fun(...)

      {

      return....//后面跟的是一个非引用

       }

例如:int  fun(int a)

     {

     return a;

    }

 

  (3)int& fun(...)

      {

      return....//后面跟的是一个引用

       }

 (4)int& fun(...)

      {

 

      return....//后面跟的是一个非引用

 

       }

上面四种函数,(1)(2)是返回非引用类型的函数,(3)(4)是返回引用类型的函数。对于返回的是哪一种类型的函数,咱们要看函数名前面的参数类型,而不是函数体内return后的类型,这点切记!!!

1、C++规定当函数返回的是非引用类型时,函数会建立临时对象(temporary object),函数返回的就是这个临时对象。在求解表达式时,若是须要一个地方存储其运算结果,编译器会建立一个没有命名的对象,这就是临时对象。浅显的说,当你调用了函数,函数会 return一个值  那么这个值总得有存放的地方吧,编译器就把会把值存放在一个没有命名法临时对象中。

看一个简单的程序

对应于(2)
#include<iostream>
int fun(int &a)
{
int b=a;
return b;
}
int main()
{
 int a=8;
 int b=fun(a);//***
return 0;
}

int b=fun(a);分析此行代码:由于fun是返回非引用函数,调用fun函数,函数体内执行return时,须要建立临时变量temp,至关于执行了 int temp;而后把return的值赋值给temp,至关于执行了temp =b;而后用temp的值初始化b,至关于执行了int b=temp。

int b=fun(a);等加于int temp;temp=b;int b=temp;

当此表达式结束后 temp会消亡,因此不能int& b=fun(a); temp是在fun中的局部变量,fun调用完,表达式结束后,temp消亡,b引用的变量temp不存在了,因此编译不会经过。

 

对应于(1)

#include<iostream>
int fun(int &a)
{
return a;
}
int main()
{
 int a=8;
 int b=fun(a);//***
return 0;
}

int b=fun(a);分析此行代码:同上,等同于int temp;temp=a//用a引用的变量的值赋值给temp;int b=temp//用temp初始化b,当表达式结束后,temp会消亡。

2、C++规定当函数返回的是引用类型时。C++primer 上说当函数返回引用类型时,没有复制返回值。相反,返回的是对象自己。

//find longer of two strings

const string &shorterString(const string &s1,const string &s2)

{

return s1.size()<s2.size()?s1:s2;

}//行参和返回类型都是指向const string对象的引用,调用函数和返回结果时,都没有复制这些string对象。

 

例以下面函数,请分析:

int a;

int& fun()

{

return a;

}//由于a是全局变量,函数的返回值是a自己,a具备全局做用域。假如a是函数内的局部变量,则函数会出错。

按照C++primer的说法 返回的是a这个全剧变量自己。为了跟返回非引用函数的统一,我本人理解返回的是对全局变量的引用即int b=fun(a);我理解为int &temp=a;int b=temp。可能这样理解有点牵强。函数返回的是引用,引用就是变量的别名,能够等同于初化它的对象,引用=变量(初始化引用的变量),因此函数返回的就算a变量自己。

 

 

int a;

 

int& fun()

 

{

 

 

int &b=a;

return b;

}//a的别名b,可是这个别名只能在fun函数体内使用,出了fun函数体就会消亡,函数返回值是引用,那么返回的其实就是a这个变量!!!

 

千万不要返回局部对象的引用

int &fun(int &a)

{

int b=a;

return b;

}

 

此函数运行会出错,由于它返回了局部对象的引用。当函数执行完毕,int b占用的存储空间会被释放,函数返回值指向了对于这个程序来讲再也不有效的内存空间。

确保返回引用安全的一个好方法是:请自问,这个引用指向哪一个在此以前存在的对象?

 

3、把返回引用以及非引用的函数赋值给其余变量

函数返回值(int Func1())时,要产生一个临时变量做为函数返回值的副本(保存该函数调用中要返回的值),而用引用返回值 (int &Func2())时,不产生值的副本。故在用函数返回值定义一个引用(int &ia = Func1())时,该引用为临 时变量的引用,因为临时变量做用域短暂,故该引用存在随时无效的危险,是不合法的。而用引用返回值时,因为不产生值的副本,故 int &i = func2();在func2()的返回值是一个静态或者全局变量的状况下的调用是合法可行的,其直接用全局数据区中的变量来 初始化引用i,固然若是Func2中的返回值是局部变量,那么固然是非法的。

不妨本身再分析一下下面的四种函数调用:

条件:
int Func1();//假设是合法函数
int &Func2();//假设是合法函数

状况:
int &i = Func2();//引用i引用的是与一个变量,这个变量做用域大于等于int &i,合法
int &ia = Func1();//引用ia引用的是临时变量,不合法
int ib = Func1();//临时变量初始化ib,合法
int ic = Func2();//Func2返回的对象(变量)自己初始化ic;
记得这好像是钱能的那本C++教程里面的题目,应该没有记错。

总结:1.返回非引用类型函数的返回值为临时对象。此对象是return 所跟对象的拷贝。

(返回类型看函数名前面的类型,而不是return后面跟的)

            return 一个引用,那么就把引用的值赋给tem

            return一个变量(对象),那么就把变量的值赋给tem

            return 一个表达式,那么就把表达式的值赋给tem

 

           2.返回引用类型函数的返回值为return所跟对象的自己。

            return 一个引用,那么返回的就是引用所指的对象自己,由于引用是对象的别名,也就   是对象(变量)名。

            return 一个对象(变量),那么返回的就是对象自己。

相关文章
相关标签/搜索