acl  3.5.3.0
singleton.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include <assert.h>
4 #include "noncopyable.hpp"
5 
6 // singleton.hpp
7 //
8 // Copyright David Abrahams 2006. Original version
9 //
10 // Copyright Robert Ramey 2007. Changes made to permit
11 // application throughout the serialization library.
12 //
13 // Distributed under the Boost
14 // Software License, Version 1.0. (See accompanying
15 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
16 //
17 // The intention here is to define a template which will convert
18 // any class into a singleton with the following features:
19 //
20 // a) initialized before first use.
21 // b) thread-safe for const access to the class
22 // c) non-locking
23 //
24 // In order to do this,
25 // a) Initialize dynamically when used.
26 // b) Require that all singletons be initialized before main
27 // is called or any entry point into the shared library is invoked.
28 // This guarentees no race condition for initialization.
29 // In debug mode, we assert that no non-const functions are called
30 // after main is invoked.
31 
32 namespace acl {
33 
34 #if defined(_WIN32) || defined(_WIN64)
35 # pragma warning(push)
36 # pragma warning(disable : 4511 4512)
37 #endif
38 
39 //////////////////////////////////////////////////////////////////////
40 // Provides a dynamically-initialized (singleton) instance of T in a
41 // way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or
42 // http://lists.boost.org/Archives/boost/2006/05/105286.php for
43 // details.
44 //
45 
46 // singletons created by this code are guarenteed to be unique
47 // within the executable or shared library which creates them.
48 // This is sufficient and in fact ideal for the serialization library.
49 // The singleton is created when the module is loaded and destroyed
50 // when the module is unloaded.
51 
52 // This base class has two functions.
53 
54 // First it provides a module handle for each singleton indicating
55 // the executable or shared library in which it was created. This
56 // turns out to be necessary and sufficient to implement the tables
57 // used by serialization library.
58 
59 // Second, it provides a mechanism to detect when a non-const function
60 // is called after initialization.
61 
62 // make a singleton to lock/unlock all singletons for alteration.
63 // The intent is that all singletons created/used by this code
64 // are to be initialized before main is called. A test program
65 // can lock all the singletons when main is entereed. This any
66 // attempt to retieve a mutable instances while locked will
67 // generate a assertion if compiled for debug.
68 
70 {
71 public:
72  static void lock()
73  {
74  get_lock() = true;
75  }
76 
77  static void unlock()
78  {
79  get_lock() = false;
80  }
81 
82  static bool is_locked() {
83  return get_lock();
84  }
85 private:
86  static bool& get_lock()
87  {
88  static bool lock_ = false;
89  return lock_;
90  }
91 };
92 
93 template<class T>
94 class singleton_wrapper : public T
95 {
96 public:
97  static bool destroyed_;
99  {
100  destroyed_ = true;
101  }
102 };
103 
104 template<class T>
106 
107 /**
108  * 单例模板类,用VC2010或GCC编译时,单例对象在 main 函数之前被执行,
109  * 所以它是线程安全的;但在 VC2003 编译成 release 版本时且打开了优化
110  * 开关,则有可能是线程不安全的,此时不能保证单例对象的构造函数在
111  * main 之前执行.
112  * 使用举例如下:
113  * class singleton_test : public acl::singleton<singlegon_test>
114  * {
115  * public:
116  * singleton_test() {}
117  * ~singleton_test() {}
118  * singleton_test& init() { return *this; }
119  * };
120 
121  * int main()
122  * {
123  * singleton_test& test = singleton_test::get_instance();
124  * test.init();
125  * ...
126  * return 0;
127  * }
128  */
129 template <class T>
131 {
132 public:
133  static T& get_instance()
134  {
135  static singleton_wrapper< T > t;
136  // refer to instance, causing it to be instantiated (and
137  // initialized at startup on working compilers)
139  use(instance_);
140  return static_cast<T &>(t);
141  }
142 
143  static bool is_destroyed()
144  {
146  }
147 
148 private:
149  static T& instance_;
150  // include this to provoke instantiation at pre-execution time
151  static void use(T const &) {}
152 };
153 
154 template<class T>
155 T& singleton< T >::instance_ = singleton< T >::get_instance();
156 
157 //////////////////////////////////////////////////////////////////////////
158 
159 /**
160  * 上面的实现在 VC2003 的 release 编译时如果打开了优化开关,则不能保证单例
161  * 的构造函数先于 main 执行,如果是在 VC2003 下编译单例程序且在多个线程下
162  * 都用单例对象时,建议使用如下的单例模板类,示例如下:
163  * class singleton_test
164  * {
165  * public:
166  * singleton_test() {}
167  * ~singleton_test() {}
168  * singleton_test& init() { return *this; }
169  * };
170 
171  * int main()
172  * {
173  * singleton_test& test = acl::singleton2<singleton_test>::get_instance();
174  * test.init();
175  * ...
176  * return 0;
177  * }
178  *
179  */
180 template <typename T>
182 {
183 private:
184  struct object_creator
185  {
186  object_creator() { singleton2<T>::get_instance(); }
187  inline void do_nothing() const {};
188  };
189  static object_creator create_object;
190 
191 public:
192  typedef T object_type;
194  {
195  static object_type obj;
196  create_object.do_nothing();
197  return obj;
198  }
199 };
200 
201 template <typename T>
202 typename singleton2<T>::object_creator singleton2<T>::create_object;
203 
204 #if defined(_WIN32) || defined(_WIN64)
205 #pragma warning(pop)
206 #endif
207 
208 } // namespace acl
static bool is_locked()
Definition: singleton.hpp:82
static void lock()
Definition: singleton.hpp:72
static T & get_instance()
Definition: singleton.hpp:133
static bool destroyed_
Definition: singleton.hpp:97
static void unlock()
Definition: singleton.hpp:77
static bool is_destroyed()
Definition: singleton.hpp:143
static object_type & get_instance()
Definition: singleton.hpp:193