I am maintaining a library that contains a Mutex class. I cannot decide if the lock() and unlock() functions exposed by this class should be const or not. I looked for similar code on the Web, and could find both implementations.
First implementation, lock() and unlock() are not const. It means someone who uses the Mutex class in a const function should put extra effort to call Mutex's functions:
class Mutex
{
public:
void lock();
void unlock();
};
class Foo
{
public:
void getBar(Bar& bar) const
{
m_mutex.lock();
bar = m_bar;
m_mutex.unlock();
}
private:
// Mutable, responsability of the user (or we could use a const_cast when needed)
mutable Mutex m_mutex;
Bar m_bar;
};
Second implementation, lock() and unlock() are const, even if that does not sound very natural (as we modify the Mutex instance), but the user does not have to bother when calling those functions in one of his const functions:
class Mutex
{
public:
void lock() const;
void unlock() const;
};
class Foo
{
public:
void getBar(Bar& bar) const
{
m_mutex.lock();
bar = m_bar;
m_mutex.unlock();
}
private:
Mutex m_mutex;
Bar m_bar;
};
What solution do you prefer ? I hope your opinions will help me to take a decision.
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)
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