Home > Software design >  Getter returns a rvalue?
Getter returns a rvalue?

Time:04-08

I know it's a bad attempt but why we cannot edit the private member via the 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;
}

I think GetA1() doesn't work because it's using a rvalue, the copy by return. But then I'm a little surprised that GetA2() can work and at last really confused that GetA3() cannot work.

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?

Thanks!

CodePudding user response:

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

Indeed. More generally, it isn't possible to change the address where any object is stored. This applies to all objects.

Does GetA3 returns a rvalue or an unmodifiable lvalue?

GetA3() is an rvalue, more specifically it is a prvalue (just like GetA1() is also a prvalue). The type of the prvalue is "pointer to int" (unlike the type of GetA1() which is just int).

CodePudding user response:

You can modify test.a with either GetA2 or GetA3. What you can't do is assign to the prvalue int * that GetA3 returns.

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
}

CodePudding user response:

From Value category's documentation:

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

Now we can make use of the above quoted statement to understand what is happening in your code.


The call expression test.GetA1() is an rvalue of type int and so cannot appear on the left hand side of an assignment.

While the call expression test.GetA2() is an lvalue of type int and so can appear on the left hand side of an assignment.

Similarly, the call expression test.Get3() is an rvalue of type int* and so cannot be used on the left hand side of an assignment.

Does GetA3 returns a rvalue or an unmodifiable lvalue?

As described above, the value category of the expression test.GetA3() is an rvalue.

  • Related