在C ++中,为什么引用在初始化时不能改变?

时间:2017-05-26 14:08:29

标签: c++

在c ++入门书中,本书说的是当参考初始化时,它无法改变。但我发现了一个问题,这里是编码:

int a[]={1,2,3,4};
for(auto &c:a)cout<<c;

然后,输出是a的元素。但是c是这里的引用,为什么它可以与数组的不同元素绑定?我不明白。

4 个答案:

答案 0 :(得分:2)

参考不会被反弹。相反,在循环的每次迭代中都会初始化一个新引用。

你的书应该提到这是一个基于范围的 for循环,如果我正在写它,我只会在之前涵盖标准{{ 1}}循环,其中迭代数组的代码将写为:

for

正如您所看到的,远程版本只是一种更方便和可读的方式来迭代一系列值(因此名称)。在这里,您将遍历int a[]={1,2,3,4}; for (int i = 0; i < 4; ++i) cout << a[i]; 数组的所有元素。

在&#34; classic&#34;版本,您使用索引进行迭代。在远程版本中,所有发生的事情都是a在每次迭代时被绑定为c的引用。

对于它的价值,原因为什么引用无法改变/反弹只是因为语言的设计方式。这是区分引用和指针的主要功能之一。

答案 1 :(得分:2)

参考没有反弹;每次迭代都会创建一个新引用。代码:

int a[]={1,2,3,4};
for(auto &c:a)cout<<c;

实际上相当于:

int a[]={1,2,3,4};
for (auto _i = std::begin(a), _e = std::end(a); _i != _e; ++_i) {
    auto &c = *_i;
    cout << c;
}

(变量_i_e是匿名的,编译器生成的详细信息,您无法直接访问。)

请注意,c在每次迭代结束时超出范围,并在下一次迭代时返回到范围内,并带有新的绑定引用。

答案 2 :(得分:2)

基于范围的循环在这方面略显混乱(尽管意图通常更清晰)。

您可能会合理地认为:​​

for(auto &c:a)

应该等同于:

for (auto &c = /*something*/; c != /*something*/; ++c)

但它不是 - 正如你所说的那样,它不可能,因为这会改变引用a所指的c的哪个元素...每次循环。

它实际上转换为:

for (auto _iter = std::begin(a); _iter != std::end(a); ++_iter)
{
  auto &c = *_iter;
  // your loop body goes here
}

其中_iter是隐藏变量的占位符,您无法真正访问(我只是展示它以说明实际发生的事情)。

现在,在这段代码中,应该清楚的是,每次输入循环体时,都会为当前元素创建一个新的本地引用 - 它恰好每次都被称为c,但它&#39 ; s总是不同的c

答案 3 :(得分:1)

由于缺乏允许它的语法,参考文献无法发生重大变化:

int A = 1;
int B = 2;
int&C = A;
    C = B;

最后一行不能使C成为B的引用;它实际上将A设置为2。

现在,我确定设计师是否真的想要,他们可以添加一种语法来重置引用 - 但是,不需要这样的功能,因此它从未添加过。