我有懒惰的单件类,需要在第一次调用时使用boost进行序列化。
标题文件:
class Singleton
{
public:
static Singleton& Instance()
{
static Singleton theSingleInstance;
return theSingleInstance;
}
void load();
private:
Singleton();
Singleton(const Singleton& root);
Singleton& operator=(const Singleton&);
std::map<std::string,std::string > m_desc;
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive& arc, const unsigned int version)
{
arc & BOOST_SERIALIZATION_NVP(m_desc);
}
const char* FILENAME = "./config.xml";
};
源文件
#include "singleton.h"
Singleton::Singleton()
{
load();
}
void Singleton::load()
{
try
{
std::ifstream f(FILENAME);
boost::archive::xml_iarchive arc(f);
arc & boost::serialization::make_nvp("Config",Instance());
}
catch(...)
{
std::cout << "Exception" << std::endl;
}
}
因此,当我尝试使用此单例启动我的代码时,它会挂起。使用调试器,我可以看到它没有多次进入load()
方法(并且没关系)。当我暂停调试器时,它会在return theSingleInstance;
行停止,但它也不会多次通过此行的断点。我做错了什么?
答案 0 :(得分:1)
你可能想要考虑给予单身人士价值语义的做法 - 如果有一天你不想让它成为一个单身人士而且你想避免重构。
另一个优点是它提供了完整的封装:
例如:
$content
答案 1 :(得分:1)
从构造函数中调用load。这意味着,当您...呼叫theSingleInstance
时,您在静态Instance
的构造函数中
:
#0 in Singleton::load at test.cpp <test.cpp>
#1 in Singleton::Singleton at test.cpp <test.cpp>
#2 in Singleton::Instance at test.cpp <test.cpp>
#3 in main at test.cpp <test.cpp>
由于构造c ++ 11函数 - 局部静态保证是线程安全的,这意味着 - 在您的实现中 - 执行将阻塞,直到实例完全构造(或构造失败,因此可以重试)。
当然,这种情况永远不会发生,因为建筑在等待自己。
0x00000000004030f5 <+629>: callq 0x402be0 <__cxa_guard_acquire@plt>
=> 0x00000000004030fa <+634>: test %eax,%eax
0x00000000004030fc <+636>: je 0x402ff1 <Singleton::load()+369>
当然,正如您已经发现的那样,在构建实例时,使用外部访问器 not 可以解决这个问题。
答案 2 :(得分:0)
答案很简单:更换此行
arc & boost::serialization::make_nvp("Config",Instance());
与
arc & boost::serialization::make_nvp("Config",*this);