首页 文章

什么是基于堆栈的参考?

提问于
浏览
2

什么是基于堆栈的引用?它们与作为对象成员的引用有何不同?标准是否谈到这些?

我在Herb Sutter写的_2547026中遇到过这个:

Q1:以下代码是否合法C?

// Example 1

string f() { return "abc"; }

void g() {
const string& s = f();
  cout << s << endl;    // can we still use the "temporary" object?
}

A1:是的 . 这是一个C功能......代码是有效的,并且完全符合它的要求 . 通常,临时对象仅持续到它出现的完整表达式的结尾 . 但是,C故意指定将临时对象绑定到堆栈上对const的引用会将临时对象的生命周期延长到引用本身的生命周期,从而避免了常见的悬空引用错误 . 在上面的示例中,f()返回的临时值一直持续到结束大括号 . (注意,这仅适用于基于堆栈的引用 . 它不适用于作为对象成员的引用 . )

4 回答

  • 4

    在给定的上下文中,基于堆栈的引用表示作为堆栈上的自动对象的引用 .

    也就是说,在

    // ...
    {
      // ...
      const foo& x = some_foo;
      // ...
    }
    // ...
    

    x 是基于堆栈的对象,而 the_foo

    class bar {
      // ...
      foo& the_foo;
      // ...
    };
    

    不是 .

  • 2

    基于堆栈的引用是一个引用,它是函数调用的参数或块内的本地非静态变量 . 所有其他引用都不是基于堆栈的 .

    int foo;
    static int &fooref = foo;  // Not stack based.
    
    class A {
     public:
       A(int &z) : x(z) {}  // z is stack based, x isn't.
       int &x;  // Not stack based.
    };
    
    void joe(int &i) { // i is stack based.
       int &k = i;  // k is stack based.
       static int &j = i;  // j is not stack base and this will likely result in a bad error later.
       A a(k);  // a is stack based, but A.x still isn't.
    }
    
  • 0

    基于堆栈的引用是基于堆的引用的替代方法 . 通常,返回值和局部变量值在“调用堆栈”中分配,“调用堆栈”是存储当前正在运行的函数序列的位置 .

    通常,当您调用函数时,堆栈中会删除“堆栈帧”,包括所有局部变量,参数和函数返回值的足够空间 . 在该函数中,该堆栈框架及其所有值保持活动状态;当函数终止时,通常会丢弃堆栈帧,然后返回上一级 .

    在这种情况下,“abc”进入f()的堆栈帧,但c足够聪明,可以在父级的堆栈帧旁边分配它;当从堆栈中弹出f()时,g()的堆栈帧(直接位于堆栈中的f()下面,因为g()调用f())被调整为挂起值“abc” .

    这描述了在堆栈上分配的对象;替代方案是堆中的对象,它们是持久的 . 堆上的OBject使用'new'和'delete'进行管理,并通过指针或堆引用保存 . 完成该功能后,堆栈对象将自动释放;必须手动释放堆上的对象 .

  • 1

    基于堆栈的引用只是存在于堆栈中的引用 .

    int main()
    {
        int a = 3;
        int &b = a;  // b is a stack-based reference
        ...
    }
    

相关问题