A: 

If you want to derive classes from the Mutex class, then it makes (some) sense to make the two functions const, then you can call it in the derived class's own const functions.

Like this:

class Foo : public Mutex {
public:
    void
        bar() const { lock(); doSomething(); unlock(); }
}
zacsek
I think this is a bad example. Using inheritance to add something to a class that can trivially be added by composition is bad style IMHO.
Martin
@Martin: It's not worse than cheating with `mutable` in the encapsulation: both methods have pros and cons. In this case it all depends on the usage pattern of the Mutex class, and how it feels more natural to the programmer, IMO.
zacsek
+6  A: 

I prefer the first option of making the Mutex mutable in the client code. By this, the user of the class explictly knows that he is calling a non-const function from his const function. In fact if you see the MFC implementation of CMutex class you can see Lock and Unlock methods are non-const.

Naveen
This sounds more natural to me as well. Another example is Qt QMutex implementation whose lock and unlock are not const either: http://doc.qt.nokia.com/4.6/qmutex.html
Longfield
+5  A: 

mutable was made for this kind of stuff. Namely, mutable applies to things that don't take part in the logical constness of an object. (If one value is "logically constant", it means the 'primary' values are constant; the value of the object, from the outside, cannot change.)

The value of your object is independent from the state of the mutex (it's only an implementation detail to provide consistency, and it's state is not known outside the class), which is a good sign your mutex should be mutable.


Note, you should not go the const_cast route. This leads to undefined behavior if you did:

const Foo f;

Bar b;
f.getBar(b); // takes const off of mutex, modifies (bang you're dead)
GMan
Does that mean that if a class has a mutable member, the compiler/linker handles it differently (i.e. unlike for "normal" const classes, its instances can't be put into a const address space)?
Péter Török
@Péter: Yup. §3.9.3/3: "Each non-static, non-mutable, non-reference data member of a const-qualified class object is const-qualified..." So a `mutable` member does not get a const-qualification.
GMan
+1 for const_cast advice
Chubsdad
+2  A: 

The first implementation is preferred: the const condition refers to logical const-ness vs. binary const-ness: the mutex is a helper class - it does not actually change the logical state of the client code, but changing it does change the binary state of the client code.

As such, the mutex should be made mutable in the client code.

The same situation arises if you are caching some costly operation results in your code: you declare the chache variable as mutable, so when computing it you don't need to throw away the const-ness of the class.

utnapistim
A: 

Thank you very much, I will go for the first option.