这里赛格故障代码,简化...访问单身般的静态成员
//A class used in the next class, Nothing much to worry about
class BasicLogger{
//...
};
下面是我的主类。它有两个你需要看的成员:它自己类型的一个静态成员(称为log
)。 而且,一个容器(称为repo
)用于保存上述类的对象。 repo
的项目,采用访问operator[]
超载:
class Logger {
protected:
// repository of profilers. each profiler is distinguished by a file name!
std::map<const std::string, boost::shared_ptr<BasicLogger> > repo;
public:
Logger(){} //breakpoints never reach here. why?
//universal singleton-like access to this class
static Logger log;
//returns a member stored in the above 'repo'
virtual BasicLogger & operator[](const std::string &key);
};
问题来源于此方法:
BasicLogger & Logger::operator[](const std::string &key)
{
std::map<std::string, boost::shared_ptr<BasicLogger> >::iterator it = repo.find(key);
if(it == repo.end()){
std::cout << "creating a new Logger for " << key << std::endl;
boost::shared_ptr<BasicLogger> t(new LogEngine(key));
std::map<const std::string, boost::shared_ptr<BasicLogger> > repo_debug;//just for debug
repo_debug.insert(std::make_pair(key,t));//ok
repo.insert(std::make_pair(key,t));//seg fault
return *t;
}
return *it->second;
}
和最后一条信息:在整个项目中,repo
容器项目像下面访问。
namespace{
BasicLogger & logger = Logger::log["path_set"];
}
问题:
的问题是,在节目的开始,任何事情之前,控制直接进入BasicLogger & logger = Logger::log["path_set"];
Q1:到底为什么不控制走在这里第一次?仅仅是因为log
是静态的还是匿名的命名空间最初也会出现?
反正, 所以当运算符[]执行时,repo
似乎是未初始化的。我添加了一个与repo
具有相同签名的本地虚拟变量(repo_debug
)。并且观察到它们的值用gdb:
//local repo_debug
Details:{... _M_header = {... _M_parent = 0x0, _M_left = 0x7fffffffdc08, _M_right = 0x7fffffffdc08}, _M_node_count = 0}}}
//main 'repo'
Details:{..._M_parent = 0x0, _M_left = 0x0, _M_right = 0x0}, _M_node_count = 0}}}
Q2。为什么repo
未初始化?基本上,为什么Logger
的构造函数没有被调用?
Q3。建议照顾这个问题是高度赞赏。 谢谢
通常你只会问只有一个问题(如果他们是严格相关的话可能会好起来) – 2014-09-26 08:22:53
我最初的看法:你的静态和全局正在比赛初始化。猜猜谁输了。 – WhozCraig 2014-09-26 08:26:12
Logger :: log'在哪里实例化,以及所有这些'logger = ...'?相同的编译单元?不同的编译单元?在第二种情况下,您遇到了麻烦,初始化顺序未定义。如果你想以这种方式使用它,创建一些吸气剂(吸气剂将首先检查并创建它,可能使用原子)。或者在一个文件中实例化所有的记录器。 – firda 2014-09-26 08:32:53