template <typename Type,
typename Traits = DefaultSingletonTraits<Type>,
typename DifferentiatingType = Type>
class Singleton {
private:
// Classes using the Singleton<T> pattern should declare a GetInstance()
// method and call Singleton::get() from within that.
friend Type* Type::GetInstance();
// Return a pointer to the one true instance of the class.
static Type* get() // 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.
static void OnExit(void* /*unused*/)
static base::subtle::AtomicWord instance_;
};
这段代码有三个泛型参数
- Type
- traits
- DifferentiatingType
有如下几个函数
- get()
- onExit() 所有的函数都是private的,只能通过一个友元函数来访问。
template<typename Type>
struct DefaultSingletonTraits {
// Allocates the object.
static Type* New() {
// The parenthesis is very important here; it forces POD type
// initialization.
return new Type();
}
// Destroys the object.
static void Delete(Type* x) {
delete x;
}
// Set to true to automatically register deletion of the object on process
// exit. See below for the required call that makes this happen.
static const bool kRegisterAtExit = true;
// Set to false to disallow access on a non-joinable thread. This is
// different from kRegisterAtExit because StaticMemorySingletonTraits allows
// access on non-joinable threads, and gracefully handles this.
static const bool kAllowedToAccessOnNonjoinableThread = false;
};
c++ 的泛型编程,确实有一些细节需要好好思考。像编译器一样。
可以看出Traits可以辅助 Singleton进行对象的创建,用定义的New和Delete函数来实现。然后剩下的 kRegisterAtExit成员变量用来进行控制程序退出时是否释放对象。除了DefaultSingletonTraits之外,还有LeakySingletonTraits 和StaticMemorySingletonTraits两个可选的traits.具体的功能大家可以看源码。
static Type* get() {
base::subtle::AtomicWord value = base::subtle::NoBarrier_Load(&instance_);
if (value != 0 && value != base::internal::kBeingCreatedMarker) {
return reinterpret_cast<Type*>(value);
}
// Object isn't created yet, maybe we will get to create it, let's try...
if (base::subtle::Acquire_CompareAndSwap(
&instance_, 0, base::internal::kBeingCreatedMarker) == 0) {
// instance_ was NULL and is now kBeingCreatedMarker. Only one thread
// will ever get here. Threads might be spinning on us, and they will
// stop right after we do this store.
Type* newval = Traits::New();
// This annotation helps race detectors recognize correct lock-less
// synchronization between different threads calling get().
base::subtle::Release_Store(
&instance_, reinterpret_cast<base::subtle::AtomicWord>(newval));
if (newval != NULL && Traits::kRegisterAtExit)
base::AtExitManager::RegisterCallback(OnExit, NULL);
return newval;
}
// We hit a race. Wait for the other thread to complete it.
value = base::internal::WaitForInstance(&instance_);
return reinterpret_cast<Type*>(value);
}
代码会先尝试获取一次对象,如果没有获取到,判断是否创建了,如果没有创建,则使用Traits::New方法来进行创建,否则说明有其他人正在访问这个Singleton对象,等待该Singleton对象。
#include "base/memory/singleton.h"
FooClass* FooClass::GetInstance() {
return Singleton<FooClass>::get();
}
这个singleton的代码很通用啊。
问题