• 单例模式


    1.最简单的单例模式,不考虑线程安全以及内存泄漏

    #pragma once
    #include <iostream>
    
    using namespace std;
    
    class Singleton
    {
    private:
        Singleton() {
            cout << "construct" << endl;
        }
        Singleton(Singleton& s) = delete; // 拷贝构造函数禁用
        Singleton& operator=(const Singleton&) = delete; // 拷贝赋值运算符禁用
        static Singleton* singleton_ptr;
    
    public:
        ~Singleton()
        {
            if (singleton_ptr != nullptr)
                delete singleton_ptr;
            cout << "desconstruct" << endl;
        }
    
        static Singleton* get_instance()
        {
            if (singleton_ptr == nullptr) // (1)注意这里不是线程安全的,当两个线程同时判断时,会进行两次实例化
                singleton_ptr = new Singleton;
            return singleton_ptr;
        }
    
    };
    Singleton* Singleton::singleton_ptr = nullptr;
    
    int main()
    {
        Singleton* ptr1 = Singleton::get_instance();
        Singleton* ptr2 = Singleton::get_instance();
    }

    上边代码有两个问题:

    1. new了一个对象,但是却没有delete,这样会造成内存泄漏,解决方法:使用智能指针
    2. (1)处会导致线程不安全,从而创建出多个对象,解决方法:加锁

    2.考虑了内存泄漏和线程安全的单例模式

    #pragma once
    #include <iostream>
    #include <memory>
    #include <mutex>
    
    using namespace std;
    
    class Singleton
    {
    private:
        Singleton() 
        {
            cout << "construct" << endl;
        }
        Singleton(Singleton& s) = delete; // 拷贝构造函数禁用
        Singleton& operator=(const Singleton&) = delete; // 拷贝赋值运算符禁用
        static shared_ptr<Singleton> singleton_ptr; // 这里指针用智能指针
        static mutex mu;
    
    public:
    
        ~Singleton()
        { 
            cout << "desconstruct" << endl;
        }
    
        static shared_ptr<Singleton> get_instance()
        {
            if (singleton_ptr == nullptr)  // 两个if语句,双检锁。只有当指针为空的时候才上锁,毕竟锁的消耗还是挺大的
            {
                lock_guard<mutex> lck(mu); // lock_guard 在构造函数里开锁,在析构函数里解锁
                if (singleton_ptr == nullptr) // 注意这里不是线程安全的,当两个线程同时判断时,会进行两次实例化
                    singleton_ptr = shared_ptr<Singleton>(new Singleton);
            }
            return singleton_ptr;
        }
    };
    
    shared_ptr<Singleton> Singleton::singleton_ptr = nullptr;
    mutex Singleton::mu;
    
    int main()
    {
        shared_ptr<Singleton> ptr1 = Singleton::get_instance();
        shared_ptr<Singleton> ptr2 = Singleton::get_instance();
    
        return 0;
    }
  • 相关阅读:
    查询表中字段相同的记录的sql
    c++ builder调用htmlencode
    win7 64位下使用regsvr32注册activex dll
    在sql 2005里创建一个和sa一样权限的账号
    c++ builder 使用indy http调用webservice方法
    sql 2005创建只读帐号的另一种方法
    C#如何用Graphics画出一幅图表
    C#中字符串的处理
    SQL语句快速介绍
    C#如何开发扫雷游戏
  • 原文地址:https://www.cnblogs.com/qiang-wei/p/12445694.html
Copyright © 2020-2023  润新知