这是一个可变成员的问题 - QMUTEX作为私人成员?

时间:2014-03-26 11:23:14

标签: c++ qt

我有以下具有私有成员的类 - QMutex - m_mutex_A;

class A
{
  public:
QMutex get_handle();

private:

 QMutex m_mutex_A;

}

QMutex A::get_handle()
{
  return m_mutex_A;
}

但是,在构建此代码段时,我遇到的问题是错误:'QMutex :: QMutex(const QMutex&)'是私有的

在Google上,我发现其中一种方法是制作QMutex m_mutex_A;如 可变的QMutex m_mutex_A;但是,这不起作用。另一个奇怪的部分是,当我将这个m_mutex_A移动到公共时,没有问题。此外,代码工作。这是什么问题?你能请点亮一下吗?我想,我在这里错过了一些基本原理。

3 个答案:

答案 0 :(得分:2)

您需要返回参考。 QMutex没有提供可访问的拷贝构造函数(当然没有意义):

class A {
public:
    QMutex& get_handle() { return m_mutex_A; }

private:
    QMutex m_mutex_A;
};

如果要在mutable方法内部使用互斥锁,则需要const关键字。

答案 1 :(得分:2)

错误告诉您QMutex的复制构造函数是私有的,因此虽然您可以将对象声明为私有成员,但您无法在get_handle中返回副本。但是,您可以返回参考:QMutex&

您可以阅读why a copy constructor is declared private here

我猜你在参考mutable时误解了google文章的上下文。 mutable关键字允许在const函数内修改变量,以及“按位const和逻辑const的区别”,如here所示。

答案 2 :(得分:1)

不应复制互斥锁。互斥锁不是句柄。不要把它当成一个。

如果class A中的互斥锁序列化了对它的访问权限,那么它应仅用于该类中的方法。班级用户不必担心。在创建类的副本时,不能复制互斥锁 - 因此您必须编写自己的副本并移动构造函数和赋值运算符。

class A {
  mutable QMutex m_mutex;
  int m_foo;
  bool m_bar;
public:
  A() : m_foo(0), m_bar(false) {}
  A(const A& other) { *this = other; }
  A& operator=(const A & rhs) {
    if (this == &rhs) return *this;
    // This guarantees that mutexes for two instances are
    // always acquired in the same order. This prevents
    // a certain class of deadlocks.
    // See http://www.justsoftwaresolutions.co.uk/threading/acquiring-multiple-locks-without-deadlock.html
    QMutexLocker lock1(qMin(&rhs.m_mutex, &m_mutex));
    QMutexLocker lock2(qMax(&rhs.m_mutex, &m_mutex)); 
    m_foo = rhs.m_foo;
    m_bar = rhs.m_bar;
  }  
  void setFoo(int foo) {
    QMutexLocker lock(&m_mutex);
    m_foo = foo;
  }
  int foo() const {
    QMutexLocker lock(&m_mutex);
    return m_foo;
  }
  void setBar(bool bar) {
    QMutexLocker lock(&m_mutex);
    m_bar = bar;
  }
  bool bar() const {
    QMutexLocker lock(&m_mutex);
    return m_bar;
  }
};

所有公共方法都是线程安全的。