设计模式——单例模式

单例模式

通常我们可以让一个全局变量使得一个对象被访问, 但它不能防止你实例化多个对象。

一个最好的办法是, 让类自身负责保存它的唯一实例。 这个类可以保证没有其他实例可以被创建, 并且提供一个可以访问该实例的方法。

 

1. 懒汉

#include <iostream>

using std::cout;
using std::endl;

class Singleton // 单例模式
{
private:
    static Singleton* m_instance_ptr;

    Singleton() // 将构造放在私有位置, 防止其他实例被创建
    {
        
    }

public:
    static Singleton *GetInstance()
    {
        if (m_instance_ptr == nullptr)
        {
            m_instance_ptr = new Singleton;
        }

        return m_instance_ptr;
    }

    ~Singleton()
    {
    }
};

Singleton* Singleton::m_instance_ptr = nullptr;

int main()
{
    Singleton *s1 = Singleton::GetInstance();
    Singleton *s2 = Singleton::GetInstance();

    cout << s1 << endl;
    cout << s2 << endl;

    system("pause");
    return 0;
}

问题

线程安全问题:加锁

内存泄漏问题:没有办法调用析构函数, 使用智能指针

 

懒汉加双重锁

#include <iostream>
#include <memory>
#include <windows.h>
#include <process.h>

using std::cout;
using std::endl;

class Singleton // 单例模式
{
public:
    typedef std::shared_ptr<Singleton> Ptr;
private:

    static Ptr m_instance_ptr;
    static HANDLE m_hMutex;

    Singleton() // 将构造放在私有位置, 防止其他实例被创建
    {
        
    }


public:
    static Ptr GetInstance()
    {
        if (m_instance_ptr == nullptr)
        {
            WaitForSingleObject(m_hMutex, NULL); // 请求锁
            if (m_instance_ptr == nullptr)
            {
                m_instance_ptr = Ptr(new Singleton);
            }
            ReleaseMutex(m_hMutex);
        }

        return m_instance_ptr;
    }
    ~Singleton()
    {
        cout << "析构" << endl;
        CloseHandle(m_hMutex);
    }


};

Singleton::Ptr Singleton::m_instance_ptr = nullptr;
HANDLE Singleton::m_hMutex = CreateMutex(NULL, TRUE, NULL);


unsigned __stdcall Thread_1( void * arg)
{
    Singleton::Ptr s = Singleton::GetInstance();

    cout << "thread_1 end" << endl;
    return 0;
}

unsigned __stdcall Thread_2( void * arg)
{
    Singleton::Ptr s = Singleton::GetInstance();
    cout << "thread_2 end" << endl;

    return 0;
}

int main()
{
    {
        HANDLE hThread_1 = (HANDLE)_beginthreadex(NULL, 0, Thread_1, NULL, 0, NULL);
        HANDLE hThread_2 = (HANDLE)_beginthreadex(NULL, 0, Thread_1, NULL, 0, NULL);
    }

    system("pause");
    return 0;
}

 

饿汉

 

posted @ 2020-08-16 13:59  x_Aaron  阅读(155)  评论(0)    收藏  举报