Reputation: 1835
This code won't compile:
class MyClass
{
boost::mutex _mutex;
void foo() const
{
boost::mutex::scoped_lock lock(_mutex);
//critical section
}
}
But defining the function as non const will work fine. Please, can someone explain why? Thanks!
Upvotes: 3
Views: 2196
Reputation: 11
Please can you explain why it didn't work. Is locking the _mutex is 'modifing' it?
Precisely, the _mutex object will change it's internal state from say "unlocked" to "locked" state. So, you need the mutable keyword fora const-function to preserve logical constness of the function while allowing the mutex to be modifiable.
Upvotes: 0
Reputation: 12907
You can't lock a mutex inside a const-member function because this actually modifies the internal state of the mutex (lock
is not itself a const
function).
If you want to keep the function const
, you'll have to declare the mutex as mutable
which is a cv-qualifier that allows const functions to modify it, i.e.
//can now be locked (i.e. modified) by a const function
mutable boost::mutex _mutex;
Using mutable
relax the const
constraints on the member variable which is declared with this qualifier, that's a way to get around constness, so be careful not to abuse this. In this case, it seems reasonable because a mutex is an internal tool of your class, and does not participate in "logical constness" (as opposed to "bitwise constness").
Upvotes: 8
Reputation: 11696
The problem occurs because boost::mutex::lock()
, which is called by the constructor of boost::mutex::scoped_lock
, is not a const
member function. Since the mutex is a member of MyClass
, that means that MyClass::_mutex::lock()
cannot be called from a non-const
member function of MyClass
.
The solution is to declare the mutex as a mutable
member. This indicates to the compiler that _mutex
may be modified, even in a const
member function:
class MyClass
{
mutable boost::mutex _mutex;
void foo() const
{
boost::mutex::scoped_lock lock(_mutex);
//critical section
}
}
Upvotes: 1
Reputation: 1312
Raistmaj is right.
The reason is that a constant method guarantees it does not change its class instance. By declaring the mutex mutable, you make an exception for that variable.
Upvotes: 1
Reputation: 756
This code should compile
class MyClass
{
mutable boost::mutex _mutex;
void foo() const
{
boost::mutex::scoped_lock lock(_mutex);
//critical section
}
}
Upvotes: 3