class Singleton
{
public:
static Singleton* getInstance()
{
static Singleton instance;
return &instance;
}
protected:
struct Object_Creator
{
Object_Creator()
{
cout<<"Object_Creator constructor"<
}
};
static Object_Creator _object_creator;
Singleton() {cout<<"Singleton constructor"<
};
Singleton::Object_Creator Singleton::_object_creator;
运行我们会看到(在 main 函数中还未使用到该单例):
Object_Creator constructor
Singleton constructor 说明,此时在main函数之前就初始化了单例对象。
对于前面的ASingleton 和 BSingleton 的例子,改进如下:
class ASingleton
{
public:
static ASingleton* getInstance()
{
static ASingleton instance;
return &instance;
}
void do_something()
{
cout<<"ASingleton do_something!"<
protected:
struct Object_Creator
{
Object_Creator()
{
ASingleton::getInstance();
}
};
static Object_Creator _object_creator;
ASingleton();
~ASingleton() {}
};
class BSingleton
{
public:
static BSingleton* getInstance()
{
static BSingleton instance;
return &instance;
}
void do_something()
{
cout<<"BSingleton do_something!"<
protected:
struct Object_Creator
{
Object_Creator()
{
BSingleton::getInstance();
}
};
static Object_Creator _object_creator;
BSingleton();
~BSingleton() {}
ASingleton::Object_Creator ASingleton::_object_creator;
BSingleton::Object_Creator BSingleton::_object_creator;
ASingleton::ASingleton()
{
cout<<"ASingleton constructor!"<
}
BSingleton::BSingleton()
{
cout<<"BSingleton constructor!"<
这样程序就避免了 ASingleton 和 BSingleton 单例对象的初始化顺序问题,使得输出结果就 始终是:
ASingleton constructor!
BSingleton constructor!
BSingleton do_something!
最后,展示一下添加了模板的实现:
template <
typename T>
class Singleton
{
struct object_creator
{
object_creator()
{
Singleton
}
inline void do_nothing() const {}
};
static object_creator create_object;
public:
typedef T object_type;
static T& instance()
{
static T obj;
//这个do_nothing是确保create_object构造函数被调用
//这跟模板的编译有关
create_object.do_nothing();
return obj;
}
};
template < typename T> typename Singleton
class QMManager
{
protected:
QMManager() {}
~QMManager() {}
friend class Singleton
public:
void do_something() {};
};
int main()
{
Singleton
return 0;
}
boost 通过添加一个类似 proxy-class 的方式,实现了单例模式,但是显然增加了复杂性,在实际应用中应该根据实际情况采用适当的实现方案。