自己的代码
template<classT>
class CSingle
{
public:
CSingle (void){}
virtual ~ CSingle (void){}
static T* GetInstance()
{
static T s_Instance;
return &s_Instance;
}
};
将Chrome 中的singleton.h代码贴上
template<typename Type,
typename Traits =DefaultSingletonTraits<Type>,
typename DifferentiatingType =Type>
classSingleton {
public:
// This class is safe to be constructed andcopy-constructed since it has no
// member.
// Return a pointer to the one true instanceof the class.
static Type* get() {
// Our AtomicWord doubles as a spinlock,where a value of
// kBeingCreatedMarker means the spinlockis being held for creation.
static const base::subtle::AtomicWordkBeingCreatedMarker = 1;
base::subtle::AtomicWordvalue =base::subtle::NoBarrier_Load(&instance_);
if (value != 0 &&value!= kBeingCreatedMarker) {
// See the corresponding HAPPENS_BEFOREbelow.
ANNOTATE_HAPPENS_AFTER(&instance_);
return reinterpret_cast<Type*>(value);
}
// Object isn't created yet, maybe we willget to create it, let's try...
if (base::subtle::Acquire_CompareAndSwap(&instance_,
0,
kBeingCreatedMarker)== 0) {
// instance_ was NULL and is nowkBeingCreatedMarker. Only one thread
// will ever get here. Threads might be spinning on us, and theywill
// stop right after we do this store.
Type*newval =Traits::New();
// This annotation helps race detectorsrecognize correct lock-less
// synchronization between differentthreads calling get().
// See the corresponding HAPPENS_AFTERbelow and above.
ANNOTATE_HAPPENS_BEFORE(&instance_);
base::subtle::Release_Store(
&instance_, reinterpret_cast<base::subtle::AtomicWord>(newval));
if (Traits::kRegisterAtExit)
base::AtExitManager::RegisterCallback(OnExit,NULL);
return newval;
}
// We hit a race. Another thread beat us and either:
// - Has the object in BeingCreated state
// - Already has the object created...
// We know value != NULL. It could be kBeingCreatedMarker, or a validptr.
// Unless your constructor can be very timeconsuming, it is very unlikely
// to hit this race. When it does, we just spin and yield thethread until
// the object has been created.
while (true) {
value = base::subtle::NoBarrier_Load(&instance_);
if (value !=kBeingCreatedMarker)
break;
PlatformThread::YieldCurrentThread();
}
// See the corresponding HAPPENS_BEFOREabove.
ANNOTATE_HAPPENS_AFTER(&instance_);
return reinterpret_cast<Type*>(value);
}
// Shortcuts.
Type& operator*() {
return *get();
}
Type* operator->() {
return get();
}
private:
// Adapter function for use withAtExit(). This should be called single
// threaded, but we might as well take theprecautions anyway.
static void OnExit(void*unused){
// AtExit should only ever be registerafter the singleton instance was
// created. We should only ever get here with a valid instance_ pointer.
Traits::Delete(reinterpret_cast<Type*>(
base::subtle::NoBarrier_AtomicExchange(&instance_,0)));
}
static base::subtle::AtomicWordinstance_;
};
template<typename Type, typenameTraits, typename DifferentiatingType>
base::subtle::AtomicWord Singleton<Type,Traits,DifferentiatingType>::
instance_ = 0;
#endif // BASE_SINGLETON_H_
如果需要使某个类单例,则从
Template<classT>
Class CA: CSingle <T>
{
}
使用的时候
CA:: GetInstance()能得到单一实例,产生的对象在PE文件的BSS区,想要将对象从内存中释放掉不是很自由。而析构的时候,在WinMain 函数退出之后才调用,但是调用的顺序很混乱。如果对象之间的有依赖关系,那么在程序结束的时候就会出现问题。解决的方法很土,使用TerminateProcess 结束。
而Chrome 中单例使用
CA*p = Singleton<CA>::get();
产生的对象在堆中,以后可以自由的删除,可以很好的控制对象的生命周期。
而且产生单例的方法是,如果你想支持单例模式就要从CSingleInstanceBase派生,是紧耦合的方式,代码量增大,而且不优雅。而google的解决方法是类似函数调用的方式 调用完成之后产生一个静态指针,下次就使用上次的指针。优雅的解决得方式 。
在释放指针的时候,将指针重新清0。
Google 处理方式考虑了:
1 堆中申请
2 可以自由释放
3 可以重复申请
4 线程安全
5 get函数可以重入
而
CSingle 中申请的时候,
1 未使用堆申请
2 不能够简单释放
3 不能重复申请
4 不是线程安全
还曾看过如下代码:
template<typename TYPE >TYPE* CSingletonT<TYPE>::getInstance()
{
if( m_pInstance ==NULL )
{
CComCritSecLock<CComCriticalSection>guard(GetUtilGlobalMutex() );
if( m_pInstance ==NULL )
{
m_pInstance = newTYPE();
}
}
return m_pInstance;
}
使用了一个全局的CRITICAL_SECTION,效率上要比 InterlockedExchangePointer效率低下,而且所有的申请对象都是用一个对象来抑制竞争关系,而竞争关系只有在同一个对象申请的时候才应该加锁,所以这个代码也是有问题的。