在C ++ 11中显然在运行时更改引用

时间:2014-09-15 13:31:30

标签: c++ c++11 reference

考虑以下C ++ 11中的简单代码,取自C++ Primer, 5th Edition

#include <iostream>
#include <string>

using std::cout;
using std::string;
using std::endl;

int main()
{
string s("Hello World!!!");
for (auto &c : s) // for every char in s (note: c is a reference)
c = toupper(c); // c is a reference, so the assignment changes the char
cout << s << endl;
return 0;
}

代码使用range for循环迭代string中的每个字符并将其更改为大写,这非常简单。让我感到困惑的是,引用c似乎在运行时发生了变化。在本书的其他地方,作者提到引用而不是对象不能在运行时改变。任何人都可以了解编译器如何解释这段代码?

3 个答案:

答案 0 :(得分:6)

你是对的,不能改变引用来引用不同的对象;它必须初始化为引用特定对象,并且在其整个生命周期内仍然是该对象的别名。

在这种情况下,参考不会改变;相反,为循环的每次迭代创建和销毁新的引用。这个范围风格的循环被定义为(或多或少)等效于旧式循环

for (auto it = s.begin(); it != s.end(); ++it) {
    auto &c = *it;
    // loop body
}

这样写的,很明显每次都有一个新的引用,而不是一个(以某种方式)更新的引用。

答案 1 :(得分:1)

对于for (auto &c : s)的每次迭代,都会创建一个新的c,在迭代结束时c超出范围。

以下大致相当于

for(int i = 0; i < s.length(); i++)
{
    auto &c = *(s+i);
    /*
        Do Stuff;
    */
}

答案 2 :(得分:0)

引用内容的值随此代码而变化。但是在定义参考的整个范围内,即(带括号)

for (auto &c : s){ // for every char in s (note: c is a reference)
    c = toupper(c);
}

引用指的是相同且唯一的变量。对于循环的每次迭代,您都会获得s中下一个元素的新引用。

无法做参考的内容确实改变了它所指的内容,即:

int i = 10;
int j = 20;
int& h = i;// j now refers to i
h = j; // modifies i, doesn't change what it refers to from i to j