为什么我可以将返回`const T&`的函数的返回值赋给`T`变量而不是`T&`变量?

时间:2014-10-05 22:19:58

标签: c++ reference

我有以下功能。它当然返回一个const引用。

const Something& getThing() {
    // 'data' is an array of pointers to Something
    const Something& item = *data[someIndex];
    return item;
}

这显然是编译:

const Something& thing = getThing();

但出于某种原因,这也会编译:

const Something thing = getThing();

即使这样编译:

Something thing = getThing();

但这不会编译:

Something& thing = getThing();

给出以下错误:

Invalid initialization of reference of type 'Something&' from expression of type 'const Something'

我不希望编译Something& thing = getThing()(因为那会将const转换为非const)。但我想了解为什么const Something thing = getThing()Something thing = getThing()编译。这种行为的技术原因是什么?

2 个答案:

答案 0 :(得分:4)

关键点有两个方面:首先,您返回一个const引用,因此该函数的用户不应该能够更改原始变量。这就是为什么你不能将函数调用的结果分配给常规引用;常规引用不会保护返回的const性质并允许修改变量。其次,当您将const ref(或任何ref)分配给常规(非ref)变量时,实际上会复制一个副本。由于您在这些情况下制作副本,因此您不需要该对象的const副本。如果要修改对象,则只需修改副本,并保留原始对象的常量,这是要求。

答案 1 :(得分:1)

这一个:

Something thing = getThing() ;

表示创建一个名为thing的新事物,该事物是从getThing返回的内容中复制的。因此返回的东西是不是const也无关紧要,因为我们正在制作一个新的对象。您始终可以通过复制其他数据来创建新的非const对象。

这与AlexD在评论中说的相同:

const double pi = 3.14;
double x = pi;    // OK! New variable copied from pi
x = x + 1;        // changes x, does not change pi

const Something thing类似,我们正在制作一个恰好是const的新对象。