为什么我可以为引用分配新值,如何引用引用呢?

gol*_*ean 32 c++ reference

我有几个与C++中引用的使用有关的问题.

  1. 在下面显示的代码中,它是如何工作的,而不是在线上给出错误q = "world";

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      char *p = "Hello";
      char* &q = p;
      cout <<p <<' '<<q <<"\n";
      q = "World"; //Why is there no error on this line
      cout <<p <<' '<<q <<"\n";
    }
    
    Run Code Online (Sandbox Code Playgroud)
    1. 如何将参考q重新初始化为其他内容?

    2. 不是字符串文字,p = "Hello"常量或只读空间?所以如果我们这样做,

      q = "World";
      
      Run Code Online (Sandbox Code Playgroud)

      不会p改变应该是常量的字符串吗?

  2. 我已经阅读了有关C++引用类型变量的内容,因为它们无法重新初始化或重新分配,因为它们作为常量指针"内部"存储.所以编译器会给出错误.

    但实际上如何重新分配参考变量呢?

    int i;
    
    int &j = i;
    
    int k;
    
    j = k; //This should be fine, but how we reassign to something else to make compiler flag an error?
    
    Run Code Online (Sandbox Code Playgroud)

    我试图抓住这个参考,并且可能错过了一些关键的事情,所以这些问题.

所以任何指出清除它的指针都会很有用.

joh*_*ohn 61

    • a)它不能,你引用的行不会改变引用q,它会改变p.
    • b)不是文字是常数,而是p指向文字的指针.指针可以改变,指向的指针不能改变. q = "world";使指针p指向其他东西.
  1. 你似乎认为这个代码

    int i;
    int &j = i;
    int k;
    j = k;
    
    Run Code Online (Sandbox Code Playgroud)

    重新分配参考,但事实并非如此.它分配的值ki,j还是指i.我猜这是你的主要误解.

  • 没有合法代码可以重新分配参考. (8认同)

tem*_*def 24

关于我认为你缺少的引用的一个重要细节是,一旦引用绑定到一个对象,你永远不能重新分配它.从那时起,无论何时使用引用,它都与使用它引用的对象无法区分.例如,在你的第一段代码中,当你写作时

q = "World";
Run Code Online (Sandbox Code Playgroud)

既然q是一个引用p,这相当于写作

p = "World";
Run Code Online (Sandbox Code Playgroud)

这只是改变p指向的位置,而不是它所指向的字符串的内容.(这也解释了它为什么不崩溃!)

至于你的第二个问题,一旦绑定到一个对象,就无法重新分配引用.如果你需要一个可以改变它的引用的引用,你应该使用指针代替.

希望这可以帮助!


Ami*_*rsh 9

需要注意的是,从 C++20 开始,可以使用 来更改类内引用变量所持有的引用placement new,就像摘自此 SO 帖子的以下示例所示:

struct C {
  int& i; // <= a reference field
  void foo(const C& other) {
    if ( this != &other ) {
      this->~C();
      new (this) C(other); // valid since C++20 even on a class 
                           // with a reference field
    }
  }
};

int main() {
    int a = 3, b = 5;
    C c1 {.i = a};
    C c2 {.i = b};
    c1.foo(c2); // the inner reference field i inside c1
                // was referring to a and now refers to b!
}
Run Code Online (Sandbox Code Playgroud)

代码:http ://coliru.stacked-crooked.com/a/4674071ea82ba31b