0

我想了解为什么可以在 C++ 中返回对类成员变量的引用,例如在以下示例中:

class Foo
{
int x;
public:
int& get_pvar()
{
return x;
}};

显然我们可以在 main() 中访问变量 x,创建一个对它的引用,然后改变它的内容:

Foo obj;
int& ref = obj.get_pvar();
ref = 7;

但这怎么可能?x 没有全局范围,也不是该类的静态成员。它类中定义。因此,它应该具有本地范围。那么,为什么返回对它的引用甚至在 main() 中创建对它的引用都不是错误的呢?

4

3 回答 3

2

您混淆了范围和生命周期。这是两个相关但最终不同的概念。

名称 的范围x是类范围。您只能x对类的成员函数(以及其他一些细节,此处不相关)中的成员使用非限定名称。

命名的成员对象的生命周期x与封闭类对象的生命周期相同。在这种情况下, 的生命周期obj.x与 相同obj。由于您在对象的生命周期内返回对对象的引用,因此一切都会检查。


您感到困惑的原因可能源于学习了具有自动存储持续时间的对象,如下所示:

{
    int x;
}

将它们的生命周期绑定到它们的词法范围(它们只能在那些花括号内命名,它们的范围)。但是,虽然对于这些对象来说是正确的,但它并不是普遍适用的。类对象可以独立于其名称范围(如您所见)而存在。有些对象可以有生命周期,但没有范围和名称。考虑:

auto* p = new Foo();

new表达式创建了一个对象,但它没有名称!所以连说话的余地都没有。这p是指针的名称,而不是新创建的对象的名称。

于 2018-12-02T07:17:23.940 回答
1

“范围”和“访问控制”是适用于名称的东西,而不是变量。说这x是私有的Foo意味着如果我们x在一些不相关的上下文中编写,将找不到该名称。

但是,如果您不需要查找名称,则仍然可以在其他上下文中访问该变量。

于 2018-12-02T07:16:23.767 回答
0

这就是引用或指针的工作方式。如果您决定导出私有字段的地址,则可以从外部对其进行更改。

这是一种不好的做法,但该语言没有任何机制来阻止开发人员这样做。

于 2018-12-02T07:15:26.280 回答