我有一个包含一些变量的类,比如一个列表和一个布尔值,可以由几个线程编写,所以用自己的互斥锁保护:
class Motel
{
// [...]
private:
list<Room> _rooms;
boost::mutex _rooms_mtx;
bool _opened;
boost::mutex _opened_mtx;
}
这段代码的问题是当我需要一个复制构造函数或一个operator =(甚至是自动生成的)时,我想把这个类放在一个地图中:
boost::map<string, Motel> all_motels;
Motel grenoble(...);
all_motels["Grenoble"] = grenoble;
这是禁止的,因为我们无法复制互斥锁:
/usr/include/boost/thread/pthread/mutex.hpp: In copy constructor ‘project::Motel::Motel(const project::Motel&)’:
/usr/include/boost/thread/pthread/mutex.hpp:33:9: error: ‘boost::mutex::mutex(const boost::mutex&)’ is private
在这种情况下我该怎么办? 提前谢谢
答案 0 :(得分:1)
这里的常见解决方案是使Motel
不可复制,并使用Motel
在堆上分配new
个对象。使用boost::noncopyable
和智能指针也是一个好主意。
class Motel : private boost::noncopyable
{
// [...]
private:
list<Room> _rooms;
boost::mutex _rooms_mtx;
bool _opened;
boost::mutex _opened_mtx;
}
boost::map<string, boost::unique_ptr<Motel> > all_motels;
all_motels["Grenoble"].reset(new Motel(...));
答案 1 :(得分:0)
您无法复制boost :: mutex(您的错误消息显示boost会阻止它,但尝试复制互斥锁是一堆蠕虫)。至少你必须为Motel编写自己的复制构造函数,你必须弄清楚如何处理互斥锁。很可能你想自己创建一个互斥锁。
答案 2 :(得分:0)
您必须提供复制构造函数和赋值重载(operator =),它们不会复制互斥锁而是复制数据。请参阅this正在运行的示例:
#include <map>
#include <boost/thread/mutex.hpp>
class foo {
public:
foo() {}
foo(foo const& cp)
: data_(cp.data_) {}
foo& operator=(foo const& cp) {
data_ = cp.data_;
return *this;
}
private:
boost::mutex mtx_;
bool data_;
};
int main(int argc, char* argv[]) {
std::map<int, foo> bar;
bar[1] = foo();
return 0;
}
互斥锁用于共享对象,而不是通过复制它们来完成。因此通常希望不能复制它们。因此,您应该使用shared_ptr(std (c++11)或boost)。然后使用shared_ptr的地图:
int main(int argc, char* argv[]) {
std::map<int, std::shared_ptr<foo>> bar; // untested but you see the point
bar[1] = std::shared_ptr<foo>(new foo);
return 0;
}
答案 3 :(得分:0)
另一个解决方案可能是使用Mutex指针。
private:
list<Room> _rooms;
boost::mutex* _rooms_mtx;
bool _opened;
boost::mutex* _opened_mtx;
}
顺便说一句,你必须确保尊重这个问题: