在const函数中使用boost :: mutex :: scoped_lock

时间:2015-03-19 14:17:05

标签: c++ const boost-mutex

此代码无法编译:

    class MyClass
    {
        boost::mutex _mutex; 

        void foo() const
        {
          boost::mutex::scoped_lock lock(_mutex);
         //critical section
        }
    }

但是将函数定义为非const将正常工作。 请问有人可以解释原因吗? 谢谢!

5 个答案:

答案 0 :(得分:6)

您无法在const-member函数中锁定互斥锁,因为这实际上会修改互斥锁的内部状态(lock本身不是const函数)。

如果要保留函数const,则必须将互斥锁声明为mutable,这是一个允许const函数修改它的cv限定符,即

//can now be locked (i.e. modified) by a const function
mutable boost::mutex _mutex;

使用mutable放宽对使用此限定符声明的成员变量的const约束,这是一种绕过constness的方法,所以请注意不要滥用它。在这种情况下,它似乎是合理的,因为互斥体是您的类的内部工具,并且不参与"逻辑常量" (而不是"按位常量")。

答案 1 :(得分:3)

此代码应编译

class MyClass
{
    mutable boost::mutex _mutex; 
    void foo() const
    {
       boost::mutex::scoped_lock lock(_mutex);
       //critical section
    }
}

答案 2 :(得分:1)

Raistmaj是对的。

原因是常量方法保证它不会更改其类实例。通过声明互斥锁是可变的,您可以为该变量设置一个例外。

答案 3 :(得分:1)

出现此问题的原因是boost::mutex::lock()boost::mutex::scoped_lock的构造函数调用, <{1}}成员函数。由于互斥锁是const的成员,这意味着无法从MyClass的非MyClass::_mutex::lock()成员函数调用const

解决方案是将互斥锁声明为MyClass成员。这向编译器表明即使在mutable成员函数中也可以修改_mutex

const

答案 4 :(得分:0)

  
    

请你能解释为什么它不起作用。锁定_mutex是'修改'吗?

  

准确地说,_mutex对象会将其内部状态从“解锁”状态更改为“已锁定”状态。因此,您需要mutable关键字fora const-function来保留函数的逻辑常量,同时允许互斥体可修改。