2

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!

4

5 回答 5

7

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

如果要保留该函数const,则必须将互斥锁声明为mutable允许 const 函数对其进行修改的 cv 限定符,即

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

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

于 2015-03-19T14:18:15.627 回答
3

这段代码应该编译

class MyClass
{
    mutable boost::mutex _mutex; 
    void foo() const
    {
       boost::mutex::scoped_lock lock(_mutex);
       //critical section
    }
}
于 2015-03-19T14:23:20.933 回答
1

Raistmaj 是对的。

原因是常量方法保证它不会改变它的类实例。通过将互斥体声明为可变,您为该变量创建了一个例外。

于 2015-03-19T14:25:42.773 回答
1

出现问题是因为boost::mutex::lock()的构造函数调用的boost::mutex::scoped_lock不是成员函数const。由于互斥锁是 的成员MyClass,这意味着MyClass::_mutex::lock()不能从 的非const成员函数调用MyClass

解决方案是将互斥锁声明为mutable成员。这向编译器表明_mutex可能会被修改,即使是在const成员函数中:

class MyClass
{
    mutable boost::mutex _mutex; 

    void foo() const
    {
      boost::mutex::scoped_lock lock(_mutex);
     //critical section
    }
}
于 2015-03-19T14:27:06.367 回答
0

请你解释为什么它不起作用。锁定 _mutex 是否正在“修改”它?

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

于 2015-03-19T14:58:28.577 回答