我的类中有一个std::map
容器变量,其中填充了嵌套类的对象:
class Logger {
private:
//...
class Tick{
///stores start and end of profiling
uint32_t start, lastTick,total;
/// used for total time
boost::mutex mutexTotalTime;
///is the profiling object started profiling?
bool started;
public:
Tick(){
begin();
}
/*
Tick(const Tick &t){
start = t.start;
lastTick = t.lastTick;
total = t.total;
started = t.started;
}
*/
uint32_t begin();
uint32_t end();
uint32_t tick(bool addToTotalTime = false);
uint32_t addUp(uint32_t value);
uint32_t getAddUp();
};
std::map<const std::string, Tick> profilers_;
//...
public:
//...
Logger::Tick & Logger::getProfiler(const std::string id)
{
std::map<const std::string, Tick>::iterator it(profilers_.find(id));
if(it != profilers_.end())
{
return it->second;
}
else
{
profilers_.insert(std::pair<const std::string, Tick>(id, Tick()));
it = profilers_.find(id);
}
return it->second;
}
//...
};
如果我不提供复制构造函数,上面的代码将无法编译,而我认为默认的复制构造函数应该已经到位了?! 我错过了任何概念吗? 感谢
答案 0 :(得分:3)
只有当您班级的所有成员都可以复制时,才可以为您生成复制构造函数。在Tick
的情况下,您有一个对象
boost::mutex mutexTotalTime;
这是不可复制的,因此编译器不会生成复制构造函数。请注意,在注释掉的复制构造函数中,您不复制互斥锁 - 因为您知道不应该复制互斥锁。编译器不知道。
作为旁注,没有必要为地图密钥明确说出const
:
std::map<const std::string, Tick> profilers_;
Map键始终为const,您的声明完全等同于
std::map<std::string, Tick> profilers_;
答案 1 :(得分:2)
boost :: mutex是不可复制的。由于Tick
有一个作为数据成员,因此Tick
也是不可复制的。这反过来使地图不可复制。
因此,要使Logger
可复制,您必须提供自己的复制构造函数,并在其中实现profilers_
的适当复制。或者,甚至可能更合适(感谢@LightnessRacesInOrbit建议),为Tick
提供适当的复制构造函数。
答案 2 :(得分:2)
问题是boost :: mutex不可复制。因此,如果您不提供复制构造函数,编译器会尝试生成默认值。默认情况下需要复制所有成员,但不能复制boost :: mutex,所以它放弃了。您的复制构造函数不会复制互斥锁。相反,它默认初始化新的,所以这可行。