• C++单例模式


    单例模式:一个类只允许存在一个对象(或多个实例共用唯一的对象),并提供他的访问方法

    实现思路:

    禁止在类的外部创建对象:私有化构造函数即可

    类的内部维护唯一的对象:静态成员变量

    提供单例对象的访问方法:静态成员函数

    具体创建方式:

    饿汉式:单例对象无论用或不用,程序启动即创建

    #include <iostream>
    using namespace std;
    
    class Singleton {  //单例模式--饿汉式
    public:
        //3.通过静态成员函数获取单例对象
        static Singleton& getS(void) {
            return S;
        }
    private:
        //1.私有化构造函数(包括拷贝构造)
        Singleton(int data=0):m_data(data){
            cout << "单例对象被创建了" << endl;
        }
        Singleton(const Singleton& );
        //拷贝构造可以只写声明不写定义,用编译器默认的定义
    private:
        int m_data;
        //2.使用静态成员变量表示唯一的对象
        static Singleton S;  //声明单例对象
    };
    
    Singleton Singleton::S(123);  //初始化,此时创建了对象
    
    int main() {
        cout << "main函数执行了" << endl;
        //通过这个提示可以发现,在主函数执行前单例对象已经创建了
    
        //Singleton a(10); 报错,因为构造函数私有化,不能创建对象,实现单例模式
    
        Singleton& s1 = Singleton::getS();  //通过静态成员函数获取单例对象
        //这种方式再获取 对象地址相同 属于同一个对象
    
        //Singleton aa = s1;报错,因为拷贝构造函数私有化,不能创建对象,实现单例模式
    
    
        return 0;
    }

    懒汉式:单例对象用时再创建,不用即销毁 

    #include <iostream>
    using namespace std;
    
    class Singleton {  //单例模式--懒汉式
    public:
        //3.通过静态成员函数获取单例对象
        static Singleton& getS(void) {
            if (S == NULL) {  //如果是空指针说明没有创建对象
                S = new Singleton(123);  //创建对象
            //用时再创建,所以放到这个函数中
                    
            }
            S_count++;
            return *S;
        }
    
        //销毁对象函数--不用即可销毁
        void release(void) {
            S_count--;
            if (S_count==0) {  //保存最后一个使用者再销毁
                delete S;
                S = NULL;
                cout << "对象销毁了" << endl;
            }
            
        }
    
        
    private:
        //1.私有化构造函数(包括拷贝构造)
        Singleton(int data=0):m_data(data){
            cout << "单例对象被创建了" << endl;
        }
        Singleton(const Singleton& );
        //拷贝构造可以只写声明不写定义,用编译器默认的定义
    private:
        int m_data;
        //2.使用静态成员变量指针表示唯一的对象
        static Singleton* S;  //声明单例对象指针
        static int S_count;   //记录使用者个数
    };
    
    Singleton* Singleton::S=NULL;  //初始化成空指针
    int Singleton::S_count = 0;
    
    int main() {
        cout << "main函数执行了" << endl;
        
        Singleton& s1 = Singleton::getS();  //通过静态成员函数获取单例对象
        //这种方式再获取 对象地址相同 属于同一个对象
    
        //Singleton aa = s1;报错,因为拷贝构造函数私有化,不能创建对象,实现单例模式
    
        
    
        Singleton& s2 = Singleton::getS();
        Singleton& s3 = Singleton::getS();
        //s1、s2、s3指向同一个对象
        //理解成三位使用者共享同一个对象
    
        s1.release();  //销毁对象
        s2.release();  
        s3.release(); 
        return 0;
    }
    #include <iostream>
    #include <mutex> 
    using namespace std;
    
    class Singleton {  
    public:
        
        static Singleton& getS(void) {
            static mutex mu;
            lock_guard<std::mutex> guard(mu); //上锁,防止别的线程进入
            if (S == NULL) {  
                S = new Singleton(123);  
            /*
            现在这个单例模式在多线程中还是有出错的机会的:两个线程几乎同时执行getS函数,此时有可能创建两个对象
            解决办法:加上互斥锁
            */
            }
            S_count++;
            return *S;
            
        }
    
       void release(void) {
            S_count--;
            if (S_count == 0) { 
                delete S;
                S = NULL;
                cout << "对象销毁了" << endl;
            }
    
        }
      
    
    private:
        
        Singleton(int data = 0) :m_data(data) {
            cout << "单例对象被创建了" << endl;
        }
        Singleton(const Singleton&);
        
    private:
        int m_data;
        
        static Singleton* S;  
        static int S_count;   
        
    };
    
    Singleton* Singleton::S = NULL;  
    int Singleton::S_count = 0;
    
    int main() {
        cout << "main函数执行了" << endl;
    
        Singleton& s1 = Singleton::getS(); 
        Singleton& s2 = Singleton::getS();
        Singleton& s3 = Singleton::getS();
        
        s1.release(); 
        s2.release();
        s3.release();
        return 0;
    }

  • 相关阅读:
    Python-深浅拷贝
    Python-生成式
    Python-手写web应用
    Python-为什么产生了GIL锁?
    Python-文件处理
    Python-线程
    10大网站设计错误 足以毁掉你的网站【转】
    [转]ASP.NET验证发生前无法调用 Page.IsValid。应在 CausesValidation=True 且已启动回发的控件
    jquery操作字符串常用方法总结及工作代码
    C#中的序列化和反序列化是什么、有什么作用、使用方法详解
  • 原文地址:https://www.cnblogs.com/liming19680104/p/13527134.html
Copyright © 2020-2023  润新知