函数返回值可以是引用吗?
当然可以,只是在函数返回引用的时候需要注意几点。以下给出讨论!
函数在返回值的时候,会产生一个临时变量作为函数返回值的副本;而函数在返回引用的时候,不会产生副本!那么既然是引用,那么到底是引用谁呢?
首先,我们知道要清楚函数返回引用的几种常见形式:
1)引用函数的参数,当然该参数(s1、s2)也是一个引用。
const string &shorter_String(const string &s1,const string &s2)
{
return s1.size()<s2.size()?s1:s2;
}
以上函数的返回值是引用类型。无论返回s1或是s2,调用函数和返回结果时,都没有复制这些string对象。简单的说,返回的引用是函数的参数s1或s2,同样s1和s2也是引用,而不是在函数体内产生的。
2)不要返回局部对象的引用,函数体内局部对象是不能被引用的,因为函数调用完局部对象会被释放。
const string &mainip(const string &s)
{
string ret=s;
return ret;
}
当函数执行完毕,程序将释放分配给局部对象的存储空间。此时,对局部对象的引用就会指向不确定的内存。
3)在类的成员函数中,返回类对象的引用(不能是函数内定义的类对象(会释放掉)),一般为this指向的对象,典型的例子是string类的赋值函数。
String& String::operator =(const String &str) //注意与“+”比较,函数为什么要用引用呢?a=b=c,可以做为左值
{
if (this == &str)
{
return *this;
}
delete [] m_string;
int len = strlen(str.m_string);
m_string = new char[len+1];
strcpy(m_string,str.m_string);
return *this;
}
引用作为返回值,必须遵守以下规则:
(1)不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。
(2)不能返回函数内部new分配的内存的引用。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一 个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成memory leak(内存泄露)。
(3)可以返回类成员的引用,但最好是const。主要原因是当对象的属性是与某种业务规则(business rule)相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常 量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。