I was re-reading c++ primer(4th ed.) today - the section on member functions and const references etc, and I came up with this wierd little program:
using std::cout;
using std::endl;
class ConstCheater
{
public:
ConstCheater(int avalue) : ccp(this), value(avalue) {}
ConstCheater& getccp() const {return *ccp;}
int value;
private:
ConstCheater* ccp;
};
int main()
{
const ConstCheater cc(7); //Initialize the value to 7
cout << cc.value << endl;
cc.getccp().value = 4; //Now setting it to 4, even though it's const!
cout << cc.value << endl;
cc.value = 4; //This is illegal
return 0;
}
My question is - why does c++ allow syntax such as this? Why can I edit normal data members in a class when it's declared const? Isn't the POINT of const to make it so that you can't modify values?
The constructor is allowed to modify the value of a
const
object, yes. But if it weren't, what could it do?Since the constructor has such access, it can "forward" it to someone else or "save" it for later. Of course, doing so might be a bad idea.
This is one instance where the safety mechanisms of C++ do not prevent you from building an ill-formed program. C++ is anything but foolproof. So, just be careful!
The real issue isn't the behavior of
ConstCheater::getccp()
- it's that there's no error on the line:which initializes a non-const pointer with what should be a const
this
pointer. However, constructors cannot beconst
(9.3.2/5, but a bit of thought should make it obvious why). So the constructor is allowed to initialize a non-const pointer with a pointer to a const object (or an object that's 'about to become' const). That's the hole you're driving though.As to why it's allowed, I imagine it would be difficult for the standard to try to close the hole since it would have to enumerate all the ways that a constructor's
this
would have to be treatedconst
and all the ways it would have to be treatednon-const
when constructing a const object. That seems like a pretty difficult task.