如果实参与引用参数不匹配,C++将生成临时变量。当前,仅当参数为const引用时,C++才允许这么做,但以前不是这样。下面来看看何种情况下,C++将生成临时变量,以及为何对const引用的限制是合理的。
首先,什么时候将创建临时变量呢?如果引用参数是const,则编译器将在下面两种情况下生成临时变量:
1、实参的类型正确,但不是左值;
2、实参的类型不正确,但可以转换为正确的类型
左值是什么呢?左值参数是可被引用的数据对象,例如,变量、数组元素、结构 成员、引用和解除引用的指针都是左值。非左值包括字面常量(用引号引起的字符串除外。它们由其地址表示)和包含多项的表达式。常规变量和const变量都可视为左值,因为可通过地址访问它们。但常规变量属于可修改的左值,而const变量属于不可修改的左值。
例如程序实例1.1
#include<iostream>
using namespace std;
double refcube(const double &ra)
{
return ra * ra * ra;
}
void main()
{
double side = 3.0;
double *pd = &side;
double &rd = side;
long edge = 5L;
double lens[4] = { 2.0,5.0,10.0,12.0 };
double c1 = refcube(side);
double c2 = refcube(lens[2]);
double c3 = refcube(rd);
double c4 = refcube(*pd);
double c5 = refcube(edge);
double c6 = refcube(7.0);
double c7 = refcube(side + 10.0);
cout << c1 << endl;
cout << c2 << endl;
cout << c3 << endl;
cout << c4 << endl;
cout << c5 << endl;
cout << c6 << endl;
cout << c7 << endl;
}
程序1.1执行结果为
27
1000
27
27
125
343
2197
那么为什么对于常量引用,这种行为是可行的,其他情况下却是不可行的呢?对于程序清单1.2中的函数swapr();
#include<iostream>
using namespace std;
void swapr(int &a,int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
void main()
{
long a = 3, b = 5;
swapr(a, b);
cout << a << " " << b << endl;
}
这里的类型不匹配,因此编译器将创建两个临时int变量,将它们初始化为3和5,然后交换临时变量的内容,而a和b保持不变。
简而言之,如果接受引用参数的函数的意图是修改作为参数传递的变量,则创建临时变量将阻止这种意图的实现。解决方法是。禁止创建临时变量。
现在来看refcube()函数,如果不修改传递参数的值,只是使用传递的值,因此临时变量不会造成任何不利的影响,反而会使函数在可处理的参数种类方面更通用。