"Const-ness" in C++

In C++ you can declare class methods as const. The idea is that a const method does not change the value of instance' member variables (and doesn't call non-const methods on them).

The idea is nice, since it allows the compiler to detect a probably undesired changes to data. But as with almost every nice feature of C++, there are times when you need a way to circumvent it, because otherwise it prevents you from doing what you need.

Imagine, for example, a proprietary collection, which has a synchronized "get" operation. In the function it needs to lock some internal data structures to ensure data integrity and then returns the result. The problem is, that to lock using some C++ locking objects usually means breaking the const constraint, if the lock object is part of the instance.

Another example - consider using logging in your const methods - if the logger is part of the instance, then write operation (which is non-const by its nature) also violates the constness of the method.

That's where we see another C++ trick - to work around this problem there is something called const_cast<T>. This casting operator adds or removes "constness" to its argument. Isn't it pretty?

Another option is to use the mutable keyword (thanks to Steven for reminding me), when declaring the members which need to be changed inside const member functions.

The more I see things like that in conventional programming languages, the more I like functional programming languages, such as ML and Haskell. In their core they don't even have a notion of a "variable" - something that can change a value. All functions are const by definition - the state of the world is the same before the function call and after it, and only the return value matters.

Topic: 

Comments

A better solution to this problem is to use the mutable keyword. A mutable member of a const object can still be modified. The assumption is that a mutable member does not change the visible state of the object.

You might be right from the syntax point of view, but think about optimization. If you mark a member variable as mutable, that would prevent the compiler from even try to optimize its usage. I think the keyword is more suitable for variables, which value comes from an external device.

I think you have mutable confused with volatile, which is what you would use for variables who's value can change in unexpected ways that might trip up the compiler's optimizations. Mutable was added specifically to overcome the problem you described and has no effect on the compiler's optimization.

You are probably right - shame on me :-)

You really saved my skin with this inofrmatoin. Thanks!

Add new comment