【问题标题】:Returning reference to a local static variable返回对局部静态变量的引用
【发布时间】:2022-08-14 00:01:39
【问题描述】:

刚开始学习 c++ 并遇到了这个函数返回对局部静态变量的引用的示例。

int& fun() {
    static int x = 10;
    return x;
}

int main() {
    int &z = fun();
    cout << fun() << \" \";
    z = 30;
    cout << fun();
    return 0;
}

int &amp;z = fun(); 行有什么作用?我们是否将引用存储在另一个引用中?我是该语言的新手,我所知道的是引用变量像别名一样引用变量。谁能解释这是如何工作的?

  • 是的zstatic 变量x 的别名。
  • 没有对参考文献的引用。语法int&amp;&amp; 是有效的,但意味着完全不同的东西。 zfun 的返回值都是 int&amp; 类型

标签: c++


【解决方案1】:

我们是否将引用存储在另一个引用中?

不,引用甚至不需要“存储”。参考是简化编程的东西。 auto&amp; thing = foo.get_value_reference(); 然后使用 thing 使代码更易于编写和调试。当您查看最终的汇编代码时,thing 甚至不必作为单独的实体存在。

int orig;
int& a = orig;
int& b = a;

b 现在是对orig 的引用——没有别的了。您不能引用参考。

【讨论】:

    【解决方案2】:

    我们是否将引用存储在另一个引用中?

    不,至少在 C\C++ 中没有引用引用。

    对我来说,参考只是一个不同的名字对于另一个变量,最后,它们都指的是同一个对象。更详细地说,抽象地说,每当你写int&amp; a = b时,你所拥有的仍然是b,并且不存在所谓的a这样的东西。 (a 只是b 的别名)

    正因为如此,我们不能有一个不同的名字,这听起来有点奇怪,因为它实际上并不指代任何存在的东西。

    在上述情况下,int&amp; fun() 所做的是返回实际的static int x = 10;。而int &amp;z = fun();,再次直接引用实际的static int x = 10;。不管是z 还是什么,毕竟只是static int x = 10,名称不同。

    如果您将符号-&amp; 删除到int fun(),这将有所不同,这将返回int x = 10; 的复制版本,这意味着现在存在两个不同的东西:int x = 10int x = 10 的副本。

    这就是 C\C++ 内存高效的原因,不是吗?你知道什么时候被复制,什么时候不被复制,这对优化有很大帮助!

    希望这可以帮助!

    【讨论】:

    • '正在返回实际'的意思,如果它稍后改变它的值,我们会看到这种变化。
    【解决方案3】:

    首先,在函数内声明的变量static 在程序开始时分配,在程序结束时释放。不像普通的局部变量,在从声明静态变量的函数返回后保持对静态变量的引用是安全的。它继续存在并将保持其价值。

    让我们考虑这个函数:

    int& fun() {
        static int x = 10;
        return x;
    }
    

    返回对静态变量的引用X就像返回变量本身一样。我们可以通过该引用增加变量,例如:

      cout << fun()++ << endl;
      cout << fun()++ << endl;  // output: 11
      cout << fun() << endl;    // output: 12
    

    如果fun() 返回价值X(整数 10)而不是对变量的引用X本身(我们可以更新其值)。

    int &amp;z = fun() 让我们通过名称引用同一个静态变量z以同样的方式:

      int &z = fun();
      cout << z++ << endl;
      cout << z++ << endl;       // output: 11
      cout << z++ << endl;       // output: 12
      cout << fun() << endl;     // output: 13
    

    函数返回类型和z必须是上述工作的参考。

    如果z不是参考而是int z 变量,我们将制作一个复制原始值并递增该值以代替静态变量X本身。

    如果函数返回类型是一个值(而不是引用),它将返回X, 不是参考X本身。在这种情况下,int f(); int &amp;z = f(); 会尝试引用临时返回值的功能。事实上,这段代码甚至无法编译。

    返回静态变量(通过引用或其他方式)的函数有其用途。其中之一是函数内的静态变量在运行时初始化,这是我们第一次运行它的声明。

    在下面的代码中,init_x() 在初始化静态变量时被调用X.第一次调用fun() 以检索x 的值时会发生这种情况。

    int& fun() {
        static int x = init_x();
        return x;
    }
    
    int main() {
        do_other_stuff();
        fun()++;  // init_x() is called here
        fun()++;
        fun()++;
    }
    

    【讨论】:

    • 静态变量(在函数范围内)是否在程序开始或首次调用函数时初始化?或者是初始化时间与分配时间不同。
    最近更新 更多