使用引用成员超出范围

时间:2018-02-10 14:17:55

标签: c++ constructor scope reference

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

#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转换为&amp; 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 ++中的引用,指针和动态内存是如何工作的。任何与此斗争的人,我建议阅读这些。

2 个答案:

答案 0 :(得分:8)

  

如果争论被破坏,我们怎么还得到值123?

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

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

答案 1 :(得分:1)

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

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