我有以下功能。它当然返回一个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()
编译。这种行为的技术原因是什么?
答案 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
的新对象。