一、作为函数形参
const引用作为函数形参,可以实现传入右值和常左值实参,我们通过和普通引用作为形参进行对比来说明这一点。
编译器报错:
将print的形参改成常左值引用,只需在int前面加一个const,再编译,结果正常。
二、接收函数返回值
我们知道:普通引用是不能接收函数返回值的!为什么?
因为函数返回时会把返回值保存到栈中一个临时的匿名变量里,当函数结束后,这个匿名变量的生命周期也就结束,将会从
栈中被销毁,也就无法获取它的引用。
还是在代码中验证这一点:
增加该匿名变量的声明周期,直到改常左值引用被销毁。
将代码改成上面的样子后,编译和输出正常:
const引用作为函数形参,可以实现传入右值和常左值实参,我们通过和普通引用作为形参进行对比来说明这一点。
首先,如下代码,将普通引用作为函数print的形参,传入右值和常左值引用,然后进行编译:
#include<iostream>
using std::cout;
using std::endl;
void print(int& a)
{
cout<<a<<endl;
}
int main()
{
int a=10;
const int& ra=a;
print(10);//传入右值
print(ra);//传入常左值引用
return 0;
}
编译器报错:
[Hyman@Hyman-PC cplus]$ g++ refer.cpp
refer.cpp: In function ‘int main()’:
refer.cpp:13: 错误:不能将类型为‘int&’的非 const 引用初始化为类型为‘int’的临时变量
refer.cpp:5: 错误:在传递‘void print(int&)’的第 1 个实参时
refer.cpp:14: 错误:将类型为‘int&’的引用初始化为类型为‘const int’的表达式无效
refer.cpp:5: 错误:在传递‘void print(int&)’的第 1 个实参时
将print的形参改成常左值引用,只需在int前面加一个const,再编译,结果正常。
#include<iostream>
using std::cout;
using std::endl;
void print(const int& a)
{
cout<<a<<endl;
}
int main()
{
int a=10;
const int& ra=a;
print(10);//传入右值
print(ra);//传入常左值引用
return 0;
}
执行结果:
[Hyman@Hyman-PC cplus]$ g++ refer.cpp
[Hyman@Hyman-PC cplus]$ ./a.out
10
10
二、接收函数返回值
我们知道:普通引用是不能接收函数返回值的!为什么?
因为函数返回时会把返回值保存到栈中一个临时的匿名变量里,当函数结束后,这个匿名变量的生命周期也就结束,将会从
栈中被销毁,也就无法获取它的引用。
还是在代码中验证这一点:
#include<iostream>
using std::cout;
using std::endl;
int get_param()
{
int i = 100;
return i;
}
int main()
{
int& ri=get_param();//使用普通引用程序无法通过编译
cout<<ri<<endl;
return 0;
}
直接用int&接收函数的返回值,程序在编译时会报错:
[Hyman@Hyman-PC cplus]$ g++ refer.cpp
refer.cpp: In function ‘int main()’:
refer.cpp:12: 错误:不能将类型为‘int&’的非 const 引用初始化为类型为‘int’的临时变量
而使用const int&时就可以接收存储函数返回值的匿名变量,因为使用常左值引用接收该变量后,会
增加该匿名变量的声明周期,直到改常左值引用被销毁。
#include<iostream>
using std::cout;
using std::endl;
int get_param()
{
int i = 100;
return i;
}
int main()
{
const int& ri=get_param();//使用常左值引用程序正常编译和执行
cout<<ri<<endl;
return 0;
}
将代码改成上面的样子后,编译和输出正常:
[Hyman@Hyman-PC cplus]$ g++ refer.cpp
[Hyman@Hyman-PC cplus]$ ./a.out
100