使用引用成员超出范围

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用引用成员超出范围相关的知识,希望对你有一定的参考价值。

这个问题涉及函数堆栈和引用成员(我读到这些成员通常被认为是不好的做法)。我的测试代码:

#include <iostream>
using namespace std;

struct Person 
{
    Person(const int& s) : score(s) {}
    const int& score;
};

int main()
{
    Person p(123);
    cout << "P's score  is: " << p.score << endl;
    return 0;
}

我们在Person的构造函数中创建一个整数对象。创建模板对象是因为将int转换为&int(这就是我们需要const的原因)。然后我们将得分点设置为构造函数的参数。最后,我们退出构造函数并销毁参数。

输出:

P's score is: 123

如果争论被破坏,我们怎么还能获得价值123呢?如果我们将参数复制给成员,那对我来说是有意义的。我的逻辑告诉我,成员会指向一个空位,这显然是不正确的。也许这个论点并没有真正被破坏,而是只是超出了范围?

当我读到这个问题时出现了这个问题:Does a const reference prolong the life of a temporary?

我发现Squirrelsama的答案很明确,我认为我理解它直到我尝试了这段代码。

更新2/12/2018:有关此内容的更多信息:What happens when C++ reference leaves it's scope?

更新2/18/2018:这个问题是在没有清楚地理解C ++中的引用,指针和动态内存如何工作的情况下做出的。任何与此斗争的人,我建议阅读这些。

答案

如果争论被破坏,我们怎么还能获得价值123呢?

因为没有什么可以保证你不会。在C ++中,访问其生命周期已结束的对象(当您访问它时临时性已死)会导致未定义的行为。未定义的行为并不意味着“崩溃”或“获得空结果”。这意味着语言规范没有规定结果。您无法从纯C ++的角度来推断程序的结果。

现在可能发生的是,您的C ++实现为该临时存储保留了存储空间。即使在p初始化之后它可能会重用该位置,但这并不意味着必须这样做。所以你最终只能通过纯粹的运气阅读“正确的价值”。

另一答案

通过在对象中存储引用,只要对象有效,唯一的保证就是跟踪对象。当对象不再有效时,您可以访问不再有效的内容。

在您的示例中,您可以在某处分配临时对象(123),并通过引用机制跟踪对象。当您使用此引用时,您无法保证您跟踪的对象仍然有效。

以上是关于使用引用成员超出范围的主要内容,如果未能解决你的问题,请参考以下文章

保留对附加节点 javascript 的引用

编译器对超出范围的变量的右值引用进行推断

PLS-00225:子程序或游标“CHR”引用超出范围

分配对局部变量的引用,如果局部变量超出范围,它会超出范围吗?

使用 Jest 模拟的服务导致“不允许 jest.mock() 的模块工厂引用任何超出范围的变量”错误

子程序或光标“用户”引用超出范围