以下程序
void display(const int& a)
{
cout << a ;
}
如果用这样的文字调用就会起作用
display(5);
但是如果没有
const
,它就无法工作。
那么
const
引用如何保持指向右值(临时对象)?
最后一个问题:
const 引用如何保持指向 R 值(匿名变量)
这就是答案。 C++ 语言表示,局部 const 引用会延长临时值的生命周期,直到包含范围结束,但会节省复制构造的成本(即,如果您要使用局部变量)。
将任何对象视为内部包含某些值的 box,并且该框可能有也可能没有名称标签,即 with 名称标签的框为
variable
,而 without 名称标签的框为 literal
。不管有没有名牌,我们有盒子。
Reference
是我们将名称标签添加到盒子中的方式。
int a = 5;
int &b = a;
我们的盒子有两个名称标签(里面有值
5
)。
const int &c = 5;
你在这里,这个盒子刚刚被命名。
以前从未有过名称的盒子的新名称必须标记为
const
。因为盒子里面的值可以通过它的名字来改变,我们不希望这种情况发生(不允许发生)到我们的literal
盒子。
回到文字的定义。文字是一个常量;例如尽管变量可能会从分配的值 5 更改为另一个值,但数字 5 的值永远不会改变。通过引用传递文字意味着该函数可以修改它,根据定义,这是您不能对文字执行的操作,这就是语言要求您使用 const 修改它的原因。我不认为 C++ 可以修改文字,即使它让你尝试,但它仍然强制执行此约定以提醒程序员文字值无法修改。
因为文字是不变的。 1 不能变成 2,
"abd"
不能变成 "edf"
。
如果 C++ 允许您通过非
const
引用获取文字,那么它会:
(1) 会在你的程序中造成混乱,因为
x == 1
可能意味着“x 等于 2”,具体取决于上下文,而 (2) 是不可能实现的,因为 void display(int& a)
应该如何知道它是否收到一个字面参考还是非字面参考?
由于这两个选项都没有意义,因此文字只能通过
const
引用传递。
实际上,从字符串文字到
char*
的已弃用转换是一个很好的例子,说明了为什么这些规则很有意义,尽管它不是引用而是指针。您可以让 char*
指向 "abc"
,但尝试实际利用 char*
的“可修改性”属性并修改 char
元素之一会导致未定义的行为。这使得整个已弃用的转换既危险又无用(在非遗留代码中)。
您不想在语言的所有其他部分遇到这样的麻烦,不是吗?
右值是一个临时的消失对象,可以读取但即将被销毁。它也是一个不能保留在赋值左侧的值(你怎么能理解给这样一个幽灵赋值呢?)
C++ 有一种非常具体的方法来处理此类实体。如果您可以通过(非常量)引用传递右值,您也可以从函数内部分配给它。因此,如果要通过引用传递 r 值,则该规则必须是 const 引用。
但这并不是全部事实,因为你确实有 r 值引用(用
&&
表示)。因此,您最终可以操作临时对象,但您必须使用右值引用明确声明您确实想要这样做。