Getter returns 右值?

Getter returns a rvalue?

我知道这是一个糟糕的尝试,但为什么我们不能通过 getter 编辑私有成员?

class A
{
    int a = 2;
public:
    int GetA1() { return a; }
    int& GetA2() { return a; }
    int* GetA3() { return &a; }
};
int main() {
    A test;
    test.GetA1() = 4;     

    test.GetA2() = 4;     
    int b = test.GetA2(); 

    int* pb = &b;
    test.GetA3() = pb;
}

我认为 GetA1() 不起作用,因为它使用了右值,即 return 的副本。但是后来我有点惊讶 GetA2() 可以工作,最后我真的很困惑 GetA3() 不能工作。

会员地址上的值好像可以改,但是地址本身不行。 GetA3 return 是右值还是不可修改的左值?

谢谢!

来自Value category's documentation

An rvalue can't be used as the left-hand operand of the built-in assignment or compound assignment operators.

现在我们可以利用上面引用的语句来了解您的代码中发生了什么。


调用表达式 test.GetA1() 是类型 intrvalue,因此不能出现在赋值的左侧。

虽然调用表达式 test.GetA2() 是类型 int 左值 ,因此可以出现在赋值的左侧。

类似地,调用表达式 test.Get3() 是类型 int*rvalue,因此不能在赋值的左侧使用。

Does GetA3 returns a rvalue or an unmodifiable lvalue?

如上所述,表达式 test.GetA3() 的值类别是 rvalue.

您可以用 GetA2GetA3 修改 test.a。您不能做的是将 GetA3 returns.

的纯右值 int * 赋值
int main() {
    A test;
    // test.GetA1() = 4; // can't assign to a prvalue int

    test.GetA2() = 4; // can assign to a lvalue int
    int * pa = &test.getA2(); // can take the address of an lvalue

    int b = test.GetA2(); 

    int* pb = &b;
    // test.GetA3() = pb; // can't assign to a prvalue int *
    *test.GetA3() = 4; // can assign to a lvalue int
}

It seems that the value on member's address can be changed, but the address itself not.

确实如此。更一般地说,不可能更改存储任何对象的地址。这适用于所有对象。

Does GetA3 returns a rvalue or an unmodifiable lvalue?

GetA3() 是一个右值,更具体地说,它是一个纯右值(就像 GetA1() 也是一个纯右值)。 prvalue 的类型是“指向 int 的指针”(不同于 GetA1() 的类型,它只是 int)。