c++ 引用的本质就是常量指针。
当引用作为函数的返回值时,应该注意以下几点:
1. 引用作为函数的返回值时,必须在定义函数时在函数名前加&
2. 用引用作函数的返回值的最大好处是在内存中不产生返回值的副本。(我认为这样不仅节省了内存,同时提高了系统运行的效率)。
3. 引用作为函数的返回值时,不能返回局部变量的引用。由于函数存在生命周期,他会在函数返回后被销毁,此时对临时变量的引用就会成为无所指的引用,程序会进入未知的状态。
#include<iostream>
using namespace std;
// 普通函数, 返回值是一个值
float temp;
float fn1(float r) {
//float temp;
temp = 3.14 * r * r;
return temp;
}
// 返回引用, 即temp的本身
float& fn2(float r) {
//float temp;
temp = 3.14 * r * r;
return temp;
}
int main() {
float a = fn1(5.0);
cout << a << endl;
system("pause");
}
上面代码的执行过程如下:
首先明确,普通函数在返回值时都会生成一个临时变量。因此,返回全局变量temp的值时,c++编译器会在内存上创建临时变量并将temp的值拷贝给该临时变量。当返回到主函数main后,赋值语句float a = fn1(5.0)会把临时变量的值再拷贝给a..
#include<iostream>
using namespace std;
// 普通函数, 返回值是一个值
float temp;
float fn1(float r) {
//float temp;
temp = 3.14 * r * r;
return temp;
}
// 返回引用, 即temp的本身
float& fn2(float r) {
//float temp;
temp = 3.14 * r * r;
return temp;
}
int main() {
float &b = fn1(5.0);
cout << b << endl;
system("pause");
}
上述代码编译不通过,首先分析为什么不通过?
上图是代码的执行过程,可以看出,当fn1()以值的形式返回时,首先创建临时变量,将temp的值拷贝给临时变量,返回到主函数时,用临时变量来初始化引用变量b,但是由于临时变量是具有生命周期的,所以临时变量会在一个完整的语句表达式结束后就会析构掉,所以b就会面临无效的危险,所以就会出错。
说了这么多,我们来分析一下为什么会造成这种现象,我认为其本质就是 临时变量 的问题,临时对象会在生命周期结束后就销毁。所以即使定义了全局变量temp, 但是它返回的确是一个 临时变量,临时变量会销毁,所以就会出现上述问题。
具备上述思想,考虑引用就很容易了,引用作为返回值的最大优势在于: 不必产生临时变量,
1. 在全局变量的条件下,就不会存在上述问题,因为全局变量在生命周期内始终存在,所以就不会存在上面的问题。
#include<iostream>
using namespace std;
// 普通函数, 返回值是一个值
float temp;
float fn1(float r) {
//float temp;
temp = 3.14 * r * r;
return temp;
}
// 返回引用, 即temp的本身
float& fn2(float r) {
//float temp;
temp = 3.14 * r * r;
return temp;
}
int main() {
float &b = fn2(5.0);
cout << b << endl;
system("pause");
}
2. 但是上面的成立条件是在全局变量下,由于全局变量是在整个生命周期内始终存在,所以不会产生问题,但是在局部变量内,仍然不能用 函数引用做返回值去初始化一个引用。 道理很简单,因为函数虽然返回值是一个引用,即变量本身, 但它由于是一个局部变量,所以仍然存在生命周期问题,会被析构掉。所以会出现指向不明造成结果是垃圾值‘
#include<iostream>
using namespace std;
// 普通函数, 返回值是一个值
float fn1(float r) {
float temp;
temp = 3.14 * r * r;
return temp;
}
// 返回引用, 即temp的本身
float& fn2(float r) {
float temp;
temp = 3.14 * r * r;
return temp;
}
int main() {
float &b = fn2(5.0);
cout << b << endl;
cout<< b++ << endl;
system("pause");
}
可见, 上述代码在b自增时会出现垃圾值,所以印证了上面的问题,可以发现,如果将上面代码的变量改成全局变量,他就会出现正常的运行结果79.5, 因为若是全局变量,就不会被析构掉,所以会产生正确的结果。