将引用作为函数返回值

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

将引用作为函数返回值

要以引用返回函数值,则函数定义时必须遵循以下格式:

类型标识符&函数名(形参列表及类型说明)

{

//函数体

}

可见,以引用返回函数值,定义函数时需要在函数名前加&。引用作为函数的返回值时,函数的返回值可以理解为函数返回了一个变量(事实上,函数返回引用时,它返回的是一个指向返回值的隐式指针),因此,值为引用的函数可以用作赋值运算符的左操作数。另外,用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本。

#include

using namespace std;

int &func()

{

static int num = 0;

return ++num;

}

void main()

{

int i;

for(i=0; i<5; i++)

cout<

cout<

func()=10;

for(i=0; i<5; i++)

cout<

cout<

}

编译并运行上述程序,其输出结果如图13.1所示,可见函数func被当作赋值运算符的左操作数来使用了。

图13.1 程序输出结果

下面再给出一个使用返回引用的函数作为左值的例子,它更有力地揭示了返回引用的函数的本质。

#include

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<

change(2) = 3.14;

change(3) = -99.99;

cout<<"修改后如下: ";

for(i = 0; i < 5; i++)

cout<

cout<

return 0;

}

编译并运行上述程序,其输出结果请读者自己实验吧。函数change的返回值为double类型的引用,而该值又是一个由其参数i指定的数组array中元素的引用。因此,在主函数中,当语句“change(2) = 3.14;”被执行时,change函数返回的其实是对数组元素array[2]的引用。通过这个引用,array[2]被赋值3.14。随后的语句“change(3) = -99.99;”同此原理。由于change返回的是数组中特定元素的引用,所以该函数可以放在赋值语句的左边用来对这个数组元素进行赋值。注意前面讲过没有数组的引用,但是指向数组元素的引用时存在的。

在把引用作为返回值时有些一些地方需要提醒大家注意。

首先,不能返回局部变量或临时变量的引用,但可以返回全局变量的引用,也就是说要注意被引用的对象不能超出作用域。主要原因是局部变量会在函数返回

后被销毁,因此被返回的引用就成为了“无所指”的引用,这是不被允许的。例如

下面这段代码就是错误的:

int &func()

{

int i = 10;

return i;

}

在Visual C++ 6.0中,上述代码在编译时会抛出警告“warning C4172: returning address of local variable or temporary”,尽管编译器没有报错,但这仍然意味着一

种不安定。而且在Visual C++ 6.0中实验上述func()函数作为左值来使用的情况,结果表明赋值并未成功,这同样告诫我们这种用法是绝对应当被禁止的。毕竟,

当函数func()返回时,局部变量i就超出了作用域。于是由func()返回的对i的引用就是未定义的引用。而且,某些对标准C++支持更强的编译器中会对上述func() 作左值的情况报错!另外,这类问题也可能会间接产生,这时的错误显得更加隐

蔽而不容易被发现,所以当返回对一个对象的引用时,务必要仔细检查这个对象

是否会超出作用域。

其次,不能返回函数内部动态分配的内存的引用。虽然不存在局部变量的被

动销毁的问题,但是在此种情况下,仍然存在一些问题。例如,被函数返回的引

用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的由new分配的空间就无法被释放,从而造成内存泄漏问题。

最后,可以返回类成员的引用,但最好是const常量。这是因为当对象的属性是与某种业务规则相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,于是有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常量引用,那么对该属性的单纯赋值就会破坏业务规则的完整性。

相关文档
最新文档