8

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

当我将 double 分配给 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 会创建一个新对象,然后分配它的引用,但是我在任何地方都找不到它。

4

5 回答 5

10

即使它看起来像,ref也不是对i.

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

对 an 的引用int不能引用 a double。因此,在标记的行中,发生了从 adouble到 an的转换,int并且转换的结果是一个临时右值。通常,当它们创建的完整表达式结束时,它们会被销毁。但是 C++ 中有一条规则允许在绑定到对const. 它被延长直到引用死亡。为此,编译器实际上在幕后为其分配了一些内存。

赋值修改了原始对象i,未命名的临时对象保持不变。

于 2013-10-08T20:14:32.580 回答
4

当您将 转换为doubleint,结果是类型的右值int。这个临时值绑定到一个常量引用变量,因此临时值的生命周期延长到引用变量的生命周期。更改原件double对此没有影响。

于 2013-10-08T20:14:14.653 回答
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,所以一个类型的临时对象int是从表达式i(即double)中创建的,但是临时对象不能绑定到int&,所以它给出编译错误,但只要你放在const那里,它编译得很好,因为类型的临时对象int可以绑定到const int&.

在第二个代码中没有发生这样的事情——没有创建临时对象。因此,当您设置i为时20,在ref第二种情况下也会发生变化因为它指i的是你没有改变!)。这解释了您的代码片段的行为。i20refrefi

希望有帮助。

于 2013-10-08T20:22:28.310 回答
0
double i = 10;
const int &ref = i; 

根据您使用此代码的编译器,也可能会产生编译错误。

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

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

于 2013-10-08T20:28:29.537 回答
-1

您可以将 int 视为一个类,而 int(double); 作为从 double 构造 int 的一种方式,您有一个对该 int 的 const 引用,该 int 是从 double 构造的。

于 2013-10-08T20:06:37.793 回答