使用引用成员超出范围

问题描述 投票:3回答:2

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

#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 ++中的引用,指针和动态内存如何工作的情况下做出的。任何与此斗争的人,我建议阅读这些。

c++ constructor scope reference
2个回答
8
投票

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

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

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


1
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.