Search code examples
c++classgetter-settermutable

How do I properly call setters on a return constant referenced class member


My problem is that I am trying to access none constant setter of a constant reference of a class member resulting in the error(C2662). If I make the values being set mutable, and the setter constant, then I am okay, but I have read that you should avoid doing this, but can't find another way to do it.

Definition of vector2D:

class vector2D {
    int _x;
    int _y;
public:
    vector2D() :
    _x(0),
    _y(0) {};

    // Getters
    int xGet() { return _x;};
    int yGet() { return _y;};

    // Setters
    void xSet(int x) {
        if (x > 100) {
            _x = 100;
            return;

        } else if (x < 0) {
            _x = 0;
            return;

        } else {
            _x = x;
            return;
        }
    };

    void ySet(int y) {
        if (y > 100) {
            _y = 100;
            return;

        } else if (y < 0) {
            _y = 0;
            return;

        } else {
            _y = y;
            return;
        }
    };
};

Definition of npc :

class npc {
    vector2D _position;
public:
    npc () {};
    const vector2D& positionGet() const{
        return _position;
    };
};

main.cpp :

main () { 
    vector2D myPos;
    myPos.xSet(2);    //Okay

    npc myGuy;
    myGuy.positionGet().xSet(2);    //C2662

    return 0;
}

What I have tried :

I tried to make xSet/ySet constant functions, but that then gives me an error(expresion must be a modifiable lvalue), which makes sense. I have been reading articles about this, but the correct way has never really been clear.

I tried making x/y mutable, and then that would let me make the setter functions constant, which does get rid of the error, but then I read that a lot of people say not to use mutable, which what other way should this be done?

I also tried to make the returned value of '_position' none constant, but isn't that not safe to do???

Note : I am also trying hard to make my questions better, and so please message/leave comment on how I could have asked this better :D


EDIT: What I have found out

So what a lot of people suggest is just to return a none constant reference of '_position', but the problem I have found with this is that you can directly assign values to the returned reference.

vector2D newPos;
myGuy.positionGet() = newPos;

Which is bad because the returned value is a private member, so therefore shouldn't be able to be directly assigned. It is also bad because if the npc is passed to a function by reference, and then the above is done it calls the destructor on the vector2D once it goes out of scope.

void functTest (npc & ch1) {
    vector2D c1;
    ch1.positionGet() = c1;

    return;
}

which for some reason also destroys ch1._position ???


Solution

  • If you want your getter to return a mutable reference, then do that.

    You want to call positionGet() and get an object that you can modify.

    So don't make it const!

    vector2D& positionGet() {
        return _position;
    };
    

    Simple as.