设计模式之单例模式

#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构造对象时,可以调用子类私有的构造函数,才能保证对象构造成功

posted @ 2018-04-26 14:47  大老虎打老虎  阅读(166)  评论(0编辑  收藏  举报