我有以下具有私有成员的类 - 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移动到公共时,没有问题。此外,代码工作。这是什么问题?你能请点亮一下吗?我想,我在这里错过了一些基本原理。
答案 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;
}
};
所有公共方法都是线程安全的。