這裏賽格故障代碼,簡化...訪問單身般的靜態成員
//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