曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4075|回复: 0
打印 上一主题 下一主题

临时变量,引用参数与 const

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2012-1-13 23:07:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如果实参与引用参数不匹配时,是否会发生语法错误?答案是,如果引用参数使用 const 来修饰可以被编译器通过,否则会被视为语法错误。

测试代码:
[C++] 纯文本查看 复制代码
double refcube (double &ra)
{
    return ra * ra * ra;
}




int main()
{


    double c6 = refcube(7.0);
    
    return 0;
}

当编译这段代码时,编译器会给出下面的错误(VS2010) :
refcube”: 不能将参数 1 从“double”转换为“double &”

然而,当用 const 来修饰 refcube() 函数中的形参时,如 refcube(const double &ra)  那么函数就可以编译通过了,也只有这样时才是被 C++ 允许的。


如果引用参数是 const ,那么编译器将在两种情况下生成临时变量:


1.  实参的类型正确,但不是左值。
2. 实参的类型不正确,但可以转换为正确的类型。


左值参数是可以被引用的数据对象,如变量,数组元素,结构成员,引用以及被解除引用的指针。非左值包括字面常量和包含多项的表达式。所以,上面第一种情况是明显的,const 类型左值不能被修改。下面看第二种情况,将上面的程序代码改为:
[C++] 纯文本查看 复制代码
double refcube (const double &ra)
{
    return ra * ra * ra;
}




int main()
{
    double size = 3.0;
    double *p = &size;
    long edge = 5L;


         //下面调用都合法
    double c6 = refcube(7.0);
    double c7 = refcube (size + 5.0);
    
        double c10 = refcube (edge);


    double c8 = refcube (size);
    double c9 = refcube (*p);
    
    
    return 0;
}

上面程序中对 refcube() 函数两次调用,第一次调用传入了一个常量的参数;第二次调用传递的是一个加法表达式;第三次调用传递的是一个 long 型的变量,类型和形参也不一致,但这三种传递方式都是合法的,因为它符合上面所说的第二种情况:实参的类型不正确,但可以转换为正确的类型。也就是说,常数,表达式,不匹配的类型只要能够转换为形参类型,那么就是合法的。而最后的两种调用明显合法。


在第一到第三种情况里,编译器都将生成一个临时的匿名变量,并让 ra 指向它。这些临时变量只在函数调用期间存在,用完后编译器可以随意将之删除。对于这个临时变量,我们可以将程序简化为在 main() 中只有一条语句如 double c6 = refcube(7.0); ,然后通过反汇编观察到(VS2010):
    double c6 = refcube(7);
004113EE DD 05 30 58 41 00    fld         qword ptr [__real@401c000000000000 (415830h)]  
004113F4 DD 9D 24 FF FF FF    fstp        qword ptr [ebp-0DCh]  
004113FA 8D 85 24 FF FF FF    lea         eax,[ebp-0DCh]  
00411400 50                   push        eax  
00411401 E8 3B FC FF FF       call        refcube (411041h)  
上面,FLD 是从内存地址加载值到浮点寄存器,FSTP 是将值存往内存中,地址 ebp-0DCH 就是这个临时变量所在的地址。


所以,像上面的 refcube() 函数的目的只是使用传递的值,而不是修改它们,那么使用临时变量是可行的,也不会有任何不利的影响,反而会使得函数在可处理的参数种类方面显得更通用些。。实际上,对于形参为 const 引用的 C++ 函数,如果实参不匹配,那么其行为类似于按值传递,为确保原始数据不被修改,将使用临时变量来存储值。


将引用参数声明为常量数据的引用理由有 3 :


1. 使用 const 可以避免无意中修改数据的编程错误。


2. 使用 const 使函数能够处理 const 和非 const 实参,否则将智能接受非 const 数据。


3. 使用 const 引用使函数能够正确生成并使用临时变量。


所以,应尽可能的将引用参数声明为 const 。



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-17 21:38 , Processed in 0.085091 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表