您可以在辅助函数中执行锁定操作:
class C {
A a;
std::mutex m; // using a standard mutex instead
A A_mover(C&& other) {
std::lock_guard<std::mutex> lock(other.m);
return std::move(other.a); // move into a temporary while locked
}
public:
C() = delete;
C(int _k) : a{_k}, m{} {}
C(C&& other) : a(A_mover(std::move(other))), m{} {}
};
如果
C
它本身由多个字段组成,将互斥体移到包装器类中。理想情况下,包装器应该只保留一个对象+一个互斥体。这使用你的
Mutex
这似乎是标准
std::mutex
不可用。
class C {
A a;
A b;
public:
C() = delete;
C(int _k, int _l) : a{_k}, b{_l} {}
C(C&& other) = default;
};
class CLocker {
public:
template<typename...Args>
CLocker(Args...args) : c(std::forward<Args>(args)...) {}
CLocker(CLocker&& other) : c(mover(std::move(other))) {}
private:
struct MutexLockGuard {
MutexLockGuard(Mutex& M) : m(M) { m.take(); }
~MutexLockGuard() { m.give(); }
Mutex& m;
};
C mover(CLocker&& other) {
MutexLockGuard lock(m);
return std::move(other.c); // move into a temporary while locked
}
C c;
Mutex m;
};
int main() {
CLocker cl1(10, 20);
CLocker cl2(std::move(cl1));
}
最后是@Jarod42建议的一个没有包装器的选项:
class MutexLockGuard {
public:
MutexLockGuard(Mutex& M) : m(M) { m.take(); }
~MutexLockGuard() { m.give(); }
private:
Mutex& m;
};
class C {
public:
C() = delete;
C(int _k, int _l) : a{_k}, b{_l}, m{} {}
C(C&& other) : C(MutexLockGuard(other.m), std::move(other)) {}
//^ delegate to protected constructor
protected:
C(MutexLockGuard, C&& other) : // do the moves while the lock is held
a{std::move(other.a)},
b{std::move(other.b)},
m{}
{}
private:
A a;
A b;
Mutex m;
};