c++操作符=类成员中有互斥对象
C++ operator= with a mutex in class member
我有一个类,其中包含一些变量,比如一个列表和一个布尔值,可以由几个线程编写,并由它们自己的互斥锁保护:
class Motel
{
// [...]
private:
list<Room> _rooms;
boost::mutex _rooms_mtx;
bool _opened;
boost::mutex _opened_mtx;
}
这段代码的问题是,当我需要复制构造函数或操作符=(即使是自动生成的)时,在我的情况下,我想把类放在一个映射中:
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
在这种情况下我该怎么做?提前感谢
这里常见的解决方案是使Motel
不可复制,并与new
一起在堆上分配Motel
对象。使用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(...));
您不能复制boost::互斥锁(您的错误消息显示boost阻止了它,但是尝试复制互斥锁是一堆蠕虫)。至少,您必须为Motel编写自己的复制构造函数,并且必须弄清楚如何处理互斥对象。您很可能希望自己创建一个互斥对象。
另一个解决方案是使用互斥指针。
private:
list<Room> _rooms;
boost::mutex* _rooms_mtx;
bool _opened;
boost::mutex* _opened_mtx;
}
顺便说一下,你必须确保尊重这些问题:
- 互斥锁会被正确创建吗?
- 互斥锁是否被正确使用?
您必须提供复制构造函数和赋值重载 (operator=),它们不是复制互斥锁,而是复制数据。请看下面的运行示例:
#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;
}
<标题>但h1>
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;
}
标题>相关文章:
- 指向设备对象成员的指针
- 访问由unique_ptr传递的对象成员
- 引用对象成员函数的成员函数
- 将 C# 对象(包含静态对象成员)作为参数传递给 C++/CLI 程序
- Lua C API - 从C++分配和使用类的对象成员
- Rapidjson 遍历并获取复杂 JSON 对象成员的值
- 类对象成员变量在调用函数时不会更改
- 对象成员变量还是继承
- C++多态性:有没有办法找到对象成员函数的地址?
- 重载对象成员的比较运算符
- 获取未初始化对象成员的地址是否定义良好?
- 在优先级队列被推送到队列后,如何编辑对象成员
- 为什么在这里调用析构函数,以及在调用该对象析构函数后如何调用对象成员函数?
- 通过 std::bind 从对象成员检索值
- 保留对象成员变量的本地副本
- 有没有办法为静态对象成员定义一个符合开关标准的常量?
- 没有默认构造函数的对象成员的 wig setter
- 对象成员数组C++默认初始化
- 如何在数组中添加对象成员
- 使用聚合创建和关联两个不同的对象成员