#include <stdio.h> #include <iostream> #include <mutex> class TestClass; template<class T> class CSingleton{ public: static T& Instance(); }; template<class T> T& CSingleton<T>::Instance(){ //注意这里模板的写法 static std::auto_ptr<T> s_instance; static std::mutex m_mutex; auto temp1 = s_instance.get(); if (s_instance.get() == NULL){ std::unique_lock<std::mutex> lock(m_mutex); //! 加锁避免同时被创建两个实例 //! CUiSingleton<T>作用域下互斥量,不需要担心不同类型之间的互斥 if (s_instance.get() == NULL){ // 第二次判断的目的在于不被多线程重复创建 s_instance = std::auto_ptr<T>(new(T)); } } return *s_instance.get(); } class TestClass: public CSingleton<TestClass>{ public: void fun(){ std::cout << "继承单例类" << std::endl; } }; int main(){ CSingleton<TestClass>::Instance().fun(); system("pause"); }
//使用
class MyClass : public CSingleton<MyClass>
{
friend class CSingleton<MyClass>;
private:
MyClass() {}
public:
...
};
今天在看的时候忽然想起了静态成员变量的初始化问题,之所以静态成员变量要在类外初始化的原因,就是要保证静态成员变量在程序启动时就初始化完成
静态成员的提出是为了解决数据共享的问题。实现共享有许多方法,如:设置全局性的变量或对象是一种方法。但是,全局变量或对象是有局限性的
在类中,静态成员可以实现多个对象之间的数据共享,并且使用静态数据成员还不会破坏隐藏的原则,即保证了安全性。因此,静态成员是类的所有对象中共享的成员,而不是某个对象的成员。
template <class T> class CSingleton : private CNoncopyable { public: // 访问单件的唯一方式 static T& Instance(); protected: CSingleton() {} static std::unique_ptr<T> s_instance_; static std::mutex mutex_; }; template<class T> std::unique_ptr<T> CSingleton<T>::s_instance_; template<class T> std::mutex CSingleton<T>::mutex_;
template <class T>
inline T& CSingleton<T>::Instance()
{
if (s_instance_.get() == NULL)
{
std::unique_lock<std::mutex> lock(mutex_); //!
//! CSingleton<T>
if (s_instance_.get() == NULL) //
{
s_instance_ = std::unique_ptr<T>(new T);
}
}
return *s_instance_.get();
}
update:
这里为什么使用的类要用友元函数及构造函数一定要private
首先说明我上面写的TestClass严格来说是错误的,因为要使用单例类就要保证只有在单例的Instance()这个函数里才能初始化,而构造函数不声明为private或标志delete,则类可以随意的生产对象
第二点,友元函数是为了父类nstance构造对象时,可以调用子类私有的构造函数,才能保证对象构造成功