• 设计模式之单例模式


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

  • 相关阅读:
    Flutter Web预览时白屏解决方法
    提高IIS并发数量设置
    学习如何看懂SQL Server执行计划(一)——数据查询篇
    Sql Server 死锁相关sql语句
    IIS共享文件站点配置
    Newtonsoft.Json保留小数Convert
    git克隆代码出现Authentication failed for “http://xxxxxx“ 解决方案
    Sql Server无用索引查询
    Sql Server索引基本知识篇
    SQL Server 锁机制 悲观锁 乐观锁 实测解析
  • 原文地址:https://www.cnblogs.com/wangshaowei/p/8952317.html
Copyright © 2020-2023  润新知