C++|剖析函数参数为const引用时,要求其指向一个生成的临时变量

如果实参与引用参数不匹配,C++将生成临时变量。当前,仅当参数为const引用时,C++才允许这样做,但以前不是这样的。

下面来看何种情况下,C++将生成临时变量,以及为何对const引用的限制是合理的。

首先,什么时候将创建临时变量呢?如果引用参数是const,则编译器将在下面两种情况下生成临时变量:

1 实参的类型正确,但不是左值;

2 实参的类型不正确,但可以转换为正确的类型。

左值是什么呢?左值参数是可被引用的数据对象,例如,变量、数组元素、结构成员、引用和解除引用的指针都是左值。非左值包括字面常量(用引号括起的字符串除外,它们由其地址表示)和包含多项的表达式。在C语言中,左值最初指的是可出现在赋值语句左边的实体,但这是引入关键字const之前的情况。现在,常规变量和const变量都可视为左值,因为可以通过地址访问它们。但常规变量可以修改左值,而const变量属于不可修改的左值。

来看下面的实例:

#include 

double refCube(const double& ra)
{
    return ra*ra*ra;
}

int main()
{
    using namespace std;
    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);   // ra is side
    double c2 = refCube(lens[2]);   // ra is lens[2]
    double c3 = refCube(rd);   // rd is side
    double c4 = refCube(*pd);   // *pd is side
    double c5 = refCube(edge);   // ra is temporary variable
    double c6 = refCube(7.0);   // ra is temporary variable
    double c7 = refCube(side+10.0);   // ra is temporary variable
    
    cout<

参数side、lens[2]、rd和*pd都是有名称的、double类型的数据对象,因此可以为其创建引用,而不需要临时变量(还记得吗,数组元素的行为与同类型的变量类似)。然而,edge虽然是变量,类型却不正确,double引用不能指向long。另一方面,参数7.0和side + 10.0的类型都正确,但没有名称,在这些情况下,编译器都将生成一个临时匿名变量,并让ra指向它。这些临时变量只在函数调用期间存在,此后编译器便可以随意将其删除。

那么为什么对于常量引用,这种行为是可行的,其他情况下却不行呢?

看下面的实例:

void swapr(int& a, int& b)
{
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}

如果在早期C++宽松的规则下,执行下面的操作将发生什么情况呢?

    long a = 3, b = 5;
    swapr(a,b);

这里的类型不匹配,因此编译器将创建两个临时int变量,将它们初始化为3和5,然后交换临时变量的内容,而a和b保持不变。

简而言之,如果接受引用参数的函数的意图是修改作为参数传递的变量,则创建临时变量将阻止这种意图的实现。解决方法是禁止创建临时变量,现在的C++标准正是这样做的(然而,在默认情况下,有些编译器仍将发出警告,而不是错误消息,因此如果看到了有关临时变量的警告,请不要忽略)。

现在来看refCube()函数。该函数的目的只是使用传递的值,而不是修改它们,因此临时变量不会造成任何不利的影响,反而会使函数在可处理的参数种类方面更通用。因此,如果声明将引用指定为const,C++将在必要时生成临时变量。实际上,对于形参为const引用的C++函数,如果实参不匹配,则其行为类似于按值传递,为确保原始数据不被修改,将使用临时变量来存储值。

如果函数调用的参数不是左值或与相应的const引用参数的类型不匹配,则C++将创建类型正确的匿名变量,将函数调用的参数的值传递给该匿名变量,并让参数来引用该变量。

-End-

页面更新:2024-04-12

标签:变量   函数   参数   常量   编译器   数组   果实   意图   有名   常规   实例   元素   对象   正确   类型

1 2 3 4 5

上滑加载更多 ↓
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top