30

以下程序

void display(const int& a)
{
    cout << a ;
}

如果用这样的文字调用将起作用

display(5);

但没有const它就行不通。

那么引用如何const继续指向 R 值(匿名变量)?

4

5 回答 5

37

对于你的最后一个问题:

const 引用如何继续指向 R 值(匿名变量)

这是答案。C++ 语言说,本地 const 引用会延长临时值的生命周期,直到包含范围结束,但可以节省复制构造的成本(即,如果您要使用局部变量)。

于 2016-03-19T15:50:26.560 回答
23

将任何对象想象成一个盒子,里面包含一些值,盒子可能有也可能没有名称标签,即带有名称标签variable的盒子和没有名称标签的盒子literal。无论名称标签是否存在,我们都有盒子。


Reference是我们将名称标签添加到我们的盒子的方式。

int a = 5;
int &b = a;

我们的盒子有两个名称标签(5里面有值)。

const int &c = 5;

你在那里,盒子刚刚命名。


以前从未有过名称的盒子的新名称必须标记为const。因为盒子里面的值可以通过它的名字来改变,我们不希望它发生(不允许发生)到我们的literal盒子上。

于 2016-03-19T15:13:55.783 回答
6

它回到了字面量的定义。字面量是常数;例如,数字 5 的值永远不会改变,尽管变量可能会从分配的值 5 更改为另一个值。通过引用传递文字意味着函数可以修改它,根据定义,这是您不能对文字做的事情,这就是语言要求您使用 const 修改它的原因。我不认为 C++ 可以修改文字,即使它让你尝试,但它仍然强制执行此约定以提醒程序员不能修改文字值。

于 2016-03-19T14:38:40.540 回答
2

因为文字是不变的。1不能变成2,"abd"也不能变成"edf"

如果 C++ 允许您通过非const引用获取文字,那么它会:

  1. 必须允许文字动态地改变它们的含义,让你把 1 变成 2。
  2. 期望程序员特别注意仅通过那些不引用文字的引用来修改值,并在您弄错时调用未定义的行为。

(1) 会在您的程序中造成混乱,因为x == 1根据上下文可能意味着“x 等于 2”,并且 (2) 是不可能实现的,因为void display(int& a)应该如何知道它是否接收到文字引用?

由于这两个选项都没有意义,因此文字只能通过const引用传递。


实际上,不推荐使用的从字符串文字到的转换char*是一个很好的例子,说明了为什么规则很有意义,尽管它不是引用而是指针。您可以char*指向"abc",但尝试实际利用 的“可修改性”属性char*并修改其中一个char元素会导致未定义的行为。这使得整个弃用的转换既危险又无用(在非遗留代码中)。

您不会希望在语言的所有其他部分都遇到这样的麻烦,对吗?

于 2016-03-19T14:45:09.853 回答
2

r 值是一个临时的消逝对象,可以读取但即将被销毁。它也是一个不能留在赋值左侧的值(你怎么能理解为这样的幽灵赋值?)

C++ 有一种非常特殊的方式来处理这种实体。如果您可以通过(非常量)引用传递 r 值,您也可以从函数内部对其进行分配。因此,如果要通过引用传递 r 值,则该规则必须是 const 引用。

但这并不是全部事实,因为您确实有 r 值引用(用 表示&&)。因此,您最终可以操作临时对象,但您必须使用 r 值引用明确声明您确实想要这样做。

于 2016-03-19T16:47:13.527 回答