什么是基于堆栈的引用?

3
什么是基于堆栈的引用?它们与作为对象成员的引用有何不同?标准是否涉及这些内容?
我在Herb Sutter撰写的一篇文章中发现了这个问题:
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()返回的临时对象一直存在,直到右花括号。请注意,这仅适用于基于堆栈的引用。对于作为对象成员的引用,它不起作用。

从措辞上看,它似乎意味着一个局部于函数的引用,而不是一个类成员的引用。 - vmpstr
4个回答

5
在给定的上下文中,基于栈的引用是指在堆栈上的自动对象所表示的引用。
也就是说,在
// ...
{
  // ...
  const foo& x = some_foo;
  // ...
}
// ...

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

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

不是。


@sbi:我明白了。现在我认为你需要编辑你的帖子,特别是变量名! - Nawaz
@sbi:如果 some_foo 实际上是 bar::the_foo 呢? - Nawaz
@Nawaz: some_foo 可以是一个临时变量。关于 someInstance.the_foo:我已经回答过了:尝试想出一种方法,用 someInstance.the_foo 初始化 x,其中 someInstance 的生命周期不会比 x 更长。 - sbi
@sbi:你误解了我的意思。我是在说在第一个例子中,some_foo 必须是一个临时对象;如果它不是临时的,而是 someInstance.the_foo,那么你仍然会说它的 x 是一个基于栈的对象吗? - Nawaz
“引用”和“对象”是互相排斥的术语——不存在“引用对象”的概念。 - fredoverflow
显示剩余4条评论

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.
}

1

基于栈的引用是堆基础引用的替代品。一般来说,返回值和局部变量值都分配在“调用栈”中,即存储当前运行函数序列的地方。

通常情况下,当您调用一个函数时,在栈上会放置一个“堆栈帧”,其中包括足够的空间来存储所有局部变量、参数和函数的返回值。在该函数中,该堆栈帧与其所有值一起保持活动状态;当函数终止时,堆栈帧通常被丢弃,然后返回到上一级。

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

这描述了在堆栈上分配的对象;另一种选择是堆上的对象,它们是持久的。使用“new”和“delete”管理堆上的对象,并通过指针或堆引用保持在原地。当您完成函数操作时,堆栈对象将自动释放;堆上的对象必须手动释放。


0
一个基于栈的引用就是指存在于栈上的引用。
int main()
{
    int a = 3;
    int &b = a;  // b is a stack-based reference
    ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接