I am using a member variable and at some point of the program I want to change it, but i prefer to "lock it" everywhere else to prevent unintended changes.
Code to explain:
class myClass {
int x; // This should be prevented to being changed most of the time
int y; // Regular variable
myclass() {x = 1;}
void foo1 () {x++; y++;} // This can change x
void foo2 () {x--; y--;} // This shouldn't be able to change x
// I want it to throw a compile error
};
The question is: Can it be achieved in some way? Something like permanent const_cast?
I know I could use constructor initialization list and constant right away, but i need to change my variable later.
Alright, all the other answers I dislike, so here's my idea: hide the variable.
#define READONLY(TYPE, VAR) const TYPE& VAR = this->VAR //C++03
#define READONLY(VARIABLE) const auto& VARIABLE = this->VARIABLE //C++11
class myClass {
int x; // This should be prevented to being changed most of the time
int y; // Regular variable
myClass() :x(1), y(2) {}
void foo1 () {// This can change x
x++;
y++;
}
void foo2 () {// This shouldn't be able to change x
READONLY(x); //in this function, x is read-only
x++; //error: increment of read-only variable 'x'
y++;
}
};
There are still ways to bypass the locking of the variable (such as this->x
), but nothing can be done for those situations.
class myClass {
int x;
mutable int y;
public:
myclass() : x(1) {}
void foo1 () {x++; y++} // this can change x or y
void foo2 () const { y--; } // this can't change x by can change y
};
If you mark a member function const
like this, you can't do anything in that member that would modify a member of the object (unless that member is mutable
or static
-- and static
isn't really a member of an object at all).
Note that this won't simply prevent you from calling a function that attempts to do such modification -- rather, a function that's marked const
but tries to modify the object state won't compile at all.
I should add, however, that I'm not at all convinced that this is really the best design. Rather the contrary, it sounds to me like your requirements on x
and y
are sufficiently complex that they would probably make more sense as separate classes that enforce the proper constraints directly (e.g., by providing an overload for operator=
that only accepts input under the correct circumstances).
In other words, the use of mutable
I've shown above is (I think) the simplest and most direct answer to the question you've asked, but it seems fairly probable that you're not really asking the question you should, and you're more likely to benefit from changing the design -- unfortunately, you haven't told us enough about the "big picture" to suggest what the better design might be.
Well, I am not sure it is worth your effort, anyway, just in case this is quiz or sth, try to combine private inheritance with friend:
class MyClassX {
protected:
MyClassX() : x(1) {}
int x;
public:
int getX() const { return x; } // read only access
};
class MyClassY {
protected:
MyClassY() : y(0) {}
int y;
friend class MyClass;
public:
int getY() const { return y; }
};
class MyClassXY : private MyClassX, private MyClassY {
public:
void foo1 () {x++; y++} // this can change x or y
};
MyClass : public MyClassXY {
public:
void foo2 () const { y--; } // this can't change x but can change y
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With