Index: base/singleton.h |
diff --git a/base/singleton.h b/base/singleton.h |
index 8435c430c49941d079cd4db649d3ec16e921edcc..b119800c2d26cd867468cd462175c18b5837f3ab 100644 |
--- a/base/singleton.h |
+++ b/base/singleton.h |
@@ -114,6 +114,13 @@ template <typename Type> intptr_t |
template <typename Type> base::subtle::Atomic32 |
StaticMemorySingletonTraits<Type>::dead_ = 0; |
+// This is a hack to work around a limitation where a template argument cannot |
+// be declared as a friend directly. This is used in the below Singleton |
+// template. |
+template <typename T> |
+struct FriendMaker { |
+ typedef T FriendType; |
+}; |
// The Singleton<Type, Traits, DifferentiatingType> class manages a single |
// instance of Type which will be created on first use and will be destroyed at |
@@ -124,15 +131,37 @@ template <typename Type> base::subtle::Atomic32 |
// singletons having the same memory allocation functions but serving a |
// different purpose. This is mainly used for Locks serving different purposes. |
// |
-// Example usages: (none are preferred, they all result in the same code) |
-// 1. FooClass* ptr = Singleton<FooClass>::get(); |
-// ptr->Bar(); |
-// 2. Singleton<FooClass>()->Bar(); |
-// 3. Singleton<FooClass>::get()->Bar(); |
+// Example usage: |
+// |
+// In your header: |
+// #include "base/singleton.h" |
+// class FooClass { |
+// public: |
+// static FooClass* GetInstance(); <-- See comment below on this. |
+// void Bar() { ... } |
+// private: |
+// FooClass() { ... } |
+// friend struct DefaultSingletonTraits<FooClass>; |
+// |
+// DISALLOW_COPY_AND_ASSIGN(FooClass); |
+// }; |
+// |
+// In your source file: |
+// FooClass* FooClass::GetInstance() { |
+// return Singleton<FooClass>::get(); |
+// } |
+// |
+// And to call methods on FooClass: |
+// FooClass::GetInstance()->Bar(); |
+// |
+// NOTE: It is important that FooClass::GetInstance() is not inlined in the |
+// header, so that when source files from multiple targets include this header |
+// they don't end up with different copies of the inlined code creating multiple |
+// copies of the singleton. |
// |
// Singleton<> has no non-static members and doesn't need to actually be |
// instantiated. It does no harm to instantiate it and use it as a class member |
M-A Ruel
2010/12/10 14:52:18
Remove that too, we don't want to encourage multip
Satish
2010/12/10 17:13:48
Done.
|
-// or at global level since it is acting as a POD type. |
+// since it is acting as a POD type. |
// |
// This class is itself thread-safe. The underlying Type must of course be |
// thread-safe if you want to use it concurrently. Two parameters may be tuned |
@@ -152,20 +181,6 @@ template <typename Type> base::subtle::Atomic32 |
// shouldn't be false unless absolutely necessary. Remember that the heap where |
// the object is allocated may be destroyed by the CRT anyway. |
// |
-// If you want to ensure that your class can only exist as a singleton, make |
-// its constructors private, and make DefaultSingletonTraits<> a friend: |
-// |
-// #include "base/singleton.h" |
-// class FooClass { |
-// public: |
-// void Bar() { ... } |
-// private: |
-// FooClass() { ... } |
-// friend struct DefaultSingletonTraits<FooClass>; |
-// |
-// DISALLOW_COPY_AND_ASSIGN(FooClass); |
-// }; |
-// |
// Caveats: |
// (a) Every call to get(), operator->() and operator*() incurs some overhead |
// (16ns on my P4/2.8GHz) to check whether the object has already been |
@@ -179,7 +194,13 @@ template <typename Type, |
typename Traits = DefaultSingletonTraits<Type>, |
typename DifferentiatingType = Type> |
class Singleton { |
- public: |
+ private: |
+#if defined(OS_WIN) |
+ friend typename FriendMaker<Type>::FriendType; |
M-A Ruel
2010/12/10 14:52:18
I think you don't need this utility class; try thi
Satish
2010/12/10 15:04:57
Doesn't work in GCC
"expected nested-name-specifie
M-A Ruel
2010/12/10 15:09:42
Try this instead.
typedef typename Type Type;
frie
Satish
2010/12/10 16:10:11
Yes I tried that too :) didn't work. I'll keep thi
|
+#else |
+ friend class FriendMaker<Type>::FriendType; |
+#endif |
+ |
// This class is safe to be constructed and copy-constructed since it has no |
// member. |
@@ -249,7 +270,6 @@ class Singleton { |
return get(); |
} |
- private: |
M-A Ruel
2010/12/10 14:52:18
Why make it public?
Satish
2010/12/10 17:13:48
This is still private, along with the rest of this
|
// Adapter function for use with AtExit(). This should be called single |
// threaded, so don't use atomic operations. |
// Calling OnExit while singleton is in use by other threads is a mistake. |