为const int&分配double。 vs int to const int&

时间:2013-10-08 20:03:56

标签: c++ int const

我试图理解C ++中的常量引用,我偶然发现了这个问题:

当我为一个const int&分配双精度时然后更改引用double的值,我的int引用的值保持不变。

    double i = 10;
    const int &ref = i;    
    i = 20;

    cout << "i: " << i << endl;      // i = 20
    cout << "&ref: " << ref << endl; // ref = 10

而在分配int时,值会发生变化。

    int i = 10;
    const int &ref = i;    
    i = 20;

    cout << "i: " << i << endl;      // i = 20
    cout << "&ref: " << ref << endl; // ref = 20

这种行为的原因是什么?我的猜测是,当分配double时,隐式转换为int会创建一个新对象,然后分配它的引用,但是我无法在任何地方找到它。

5 个答案:

答案 0 :(得分:10)

即使看起来如此,ref也不是对i的引用。

double i = 10;
const int &ref = i;   // ***
i = 20;

int的引用不能引用double。因此,在标记的行中,会发生从doubleint的转换,转换结果是临时右值。 Normaly,当他们在结尾创造出完整的表达时,他们就会被摧毁。但是C ++中有一条规则允许在绑定到const的引用时延长临时生命周期。它被延长直到参考死亡。为此,编译器实际上在幕后为它分配了一些内存。

分配修改原始对象i,未命名的临时对象保持不变。

答案 1 :(得分:4)

double转换为int时,结果是int类型的右值。此临时值绑定到常量引用变量,因此临时值的生命周期将扩展为引用变量的生存期。更改原始double对此没有影响。

答案 2 :(得分:3)

只有从两个声明中删除const并尝试编译代码片段时,编译器才能为您提供帮助:

double i = 10;
/*const*/ int &ref = i;    //ERROR - WHY?

此代码将给出编译错误!为什么呢?

但是这段代码:

int i = 10;
/*const*/ int &ref = i;   //NO ERROR

编译正常。

如果第一个代码在const时编译正常,为什么现在不编译(当const不存在时)?引擎盖下发生了什么?

原因是,实际上int&是一种引用类型,它只能引用int类型的对象,而不是double,所以a int类型的临时对象是从表达式idouble)创建的,但临时对象无法绑定到int&,因此它提供了编译错误,但只要您将const放在那里,就可以很好地编译,因为int类型的临时对象可以绑定到const int&

第二个代码中没有发生这种情况 - 没有创建临时对象。因此,当您将i设置为20时,ref也会在第二种情况下更改(因为它引用i),但在第一种情况下,当您设置i时1}}到20ref执行更改,因为ref 再次引用i - 它指的是临时对象(你更改!)。这解释了代码段的行为。

希望有所帮助。

答案 3 :(得分:0)

double i = 10;
const int &ref = i; 

根据您使用此代码的编译器,也可以提供编译错误。

在抛出错误的编译器上,如果将其强制转换为(int &),您将看到未定义的行为,因为您正在从double的位置读取int。 在接受此行的编译器上,我最好的猜测是它创建一个临时变量(一个rvalue)并分配给int引用,并且对原始变量的任何更改都不会反映在引用中。

对于工作参考,请确保源数据类型可以由目标数据类型表示。

答案 4 :(得分:-1)

您可以将int视为一个类,并将int(double)视为;作为从double构造int的一种方法,你有一个对这个int的const引用,它是从double构造的。