引用作为函数的返回值有两个作用
一 可以不产生临时变量,减少内存空间的开辟
二 可以作为表达式的左值
先来第一个:
double temp;
double &sqr(double a){
temp=a*a;
return temp;}
double x=sqr(5);
cout<<x;
解释:
对于函数
A func()
如果调用
A a;
a = func()
在函数返回时
会构造一个临时变量 调用对应构造函数 使用真实返回的值来构造临时变量
然后把这个临时变量用对应的operator=函数赋值给a
析构临时变量
如果A为系统类型,那么这个过程可以简化为
分配临时变量空间并赋值
把临时变量赋值给a
释放临时变量
如果用引用来做 A&func()
那么可以省去分配空间以及释放的过程 提高效率
用引用做返回值时 要确保返回的值在退出函数后仍有效
即不能用局部变量作为函数返回值
再来第二个,可以作为表达式的左值:
#include <iostream>
using namespace std;
double array[5] = {100.1, 100.2, 100.3, 100.4, 100.5};
double &change(int i)
{
return array[i];
}
int main()
{
int i;
cout<<"原始值如下: ";
for(i = 0; i < 5; i++)
cout << array[i] <<" ";
cout<<endl;
change(2) = 3.14;
change(3) = -99.99;
cout<<"修改后如下: ";
for(i = 0; i < 5; i++)
cout<<array[i]<<" ";
cout<<endl;
system("pause");
return 0;
}
三:那在有些情况下,函数的返回值只能是引用,而有些情况函数的返回值只能是对象
比如 流操作符“<<”和赋值运算符“=”
有关流操作符:
例如:cout << “hello” << endl; 因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包括:返回一个流对象和返回一个流对象指针。但是对于返回一个流对象,程序必须重新(拷贝)构造一个新的流对象,也就是说,连续的两个<<操作符实际上是针对不同对象的!这无法让人接受。对于返回一个流指针则不能连续使用<<操作符。因此,返回一个流对象引用是惟一选择。
有关赋值操作符:
赋值操作符=。这个操作符象流操作符一样,是可以连续使用的,例如:x = j = 10;或者(x=10)=100;赋值操作符的返回值必须是一个左值,以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。
四:使用引用作为函数返回值的注意情况:
1。不能返回局部变量的引用,局部变量会在函数返回后被销毁。
2. 不能返回函数内部new分配的内存的引用,虽然不存在局部变量的被动销毁问题,但是函数返回的引用只是作为一个临时变量出现,并没有被赋予一个实际的变量,导致引用所指向的空间无法释放。
3 可以返回类成员的引用,但最好是const,主要原因是当对象的属性与某种业务规则相关联的时候,其赋值常常与某些其它属性或者对象的状态相关联,因此有必要将赋值操作封装在一个业务规则中,如果其它对象可以获得该属性的非常量引用(或指针),那么对于该属性的单纯赋值就会破坏业务规则的完整性。
其中第二三条我还没看懂