我有以下代码:
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include <memory>
class Logger : public std::ofstream
{
public:
explicit Logger(std::string const& filename = "log.txt"):
std::ofstream(filename.c_str())
{
assert(*this);
*this << "-- log file start --\n" << std::endl;
}
Logger::~Logger()
{
*this << "\n-- log file end --" << std::endl;
this->close();
this->clear();
}
};
Logger logger;
template<class T>
class NotCopyable
{
public:
NotCopyable() { }
~NotCopyable() { }
private:
NotCopyable(NotCopyable const&);
NotCopyable const& operator=(NotCopyable const&);
};
template<class T>
class Singleton : public NotCopyable<Singleton<T> >
{
public:
static T& GetInstance()
{
if (!instance)
{
logger << "Initialize Singleton" << std::endl;
instance.reset(new T());
}
return *instance;
}
protected:
Singleton() { }
virtual ~Singleton() { }
private:
static std::unique_ptr<T> instance;
};
template<class T>
std::unique_ptr<T> Singleton<T>::instance;
class Factory : public Singleton<Factory>
{
public:
Factory() { logger << "Factory constructor" << std::endl; }
~Factory() { logger << "Factory destructor" << std::endl; }
void Blargl() { logger << "Blargl" << std::endl; }
};
bool DoStuff()
{
Factory::GetInstance().Blargl();
return true;
}
bool Thingy = DoStuff();
int main(int, char*[])
{
logger << "Start main()" << std::endl;
Factory::GetInstance().Blargl();
logger << "End main()" << std::endl;
}
这输出以下内容:
-- log file start --
Initialize Singleton
Factory constructor
Blargl
Start main()
Initialize Singleton
Factory constructor
Blargl
End main()
Factory destructor
-- log file end --
我觉得很愚蠢,但看不出为什么工厂被建造两次而不是一次。这是怎么回事?
答案 0 :(得分:4)
我尝试运行您的代码,并且具有您在OSX,Apple llvm 5.0上描述的相同行为 如果在GetInstance()方法中定义静态实例变量,它可以正常工作:
static T& GetInstance()
{
static std::unique_ptr<T> instance
if (!instance)
{
logger << "Initialize Singleton" << std::endl;
instance.reset(new T());
}
return *instance;
}
我认为您的代码中存在的问题是Singleton :: instance在其声明点(默认构造函数)的初始化与GetInstance()方法中的赋值之间的未指定执行顺序。
所以,如果我说的是对的,那么执行的顺序可能就像:
GetInstance()
来自DoStuff()
来电Singleton<Factory>::instance
GetInstance()
main()
来电
醇>
编辑:使用以下代码测试我的理论:
template <typename T>
class Ptr {
public:
Ptr()
: p() {
std::cout << "Initalizing Ptr" << std::endl;
}
std::unique_ptr<T> p;
};
template<class T>
class Singleton : public NotCopyable<Singleton<T>> {
public:
static T& GetInstance()
{
if (!instance.p)
{
std::cout << "Initalizing Singleton" << std::endl;
logger << "Initialize Singleton" << std::endl;
instance.p.reset(new T());
}
return *instance.p;
}
protected:
Singleton() { }
virtual ~Singleton() { }
private:
static Ptr<T> instance;
};
template<class T>
Ptr<T> Singleton<T>::instance;
输出: