单例模式

一、概念

一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全 局访问点,该实例被所有程序模块共享。

二、恶汉模式

不管是否使用,在程序启动时就创建的唯一实例对象

class Singleton
{
    public:
        static Singleton* GetInstrance()
        {
            return &m_ps;
        }
    private:
        Singleton(Singleton &s)
        {}
    private:
        static Singleton m_ps;
};

Singleton Singleton::m_ps;

三、懒汉模式

1. 注意

(1)保证只能创建一个对象,将构造函数定义成私有的成员函数

(2)提供一个静态成员的方法:如果对象没有创建,创建对象

(3)防止被拷贝

2. 缺陷

(1)线程不安全 -- 加锁

(2)只要有一个线程获取对象,所有线程都会被阻塞 -- 双阻塞 -- 降低阻塞概率

(3)如果编译器对代码指针进行重排,对象可能船检不完整

(4)什么时机释放单例对象:保证所有线程都不使用 -- 在程序退出时

          封住内部类,在内部类析构函数中释放单例,并在单例类中创建内部类的对象

3. 代码

#include <iostream>
#include <string.h>
#include <thread>
#include <mutex>

using namespace std;

class Singleton
{
    public:
        static Singleton* GetInstrance();

        class GC
        {
            public:
                ~GC();
        };

    private:
        Singleton();
        Singleton(const Singleton&);
        Singleton& operator=(Singleton const&);

    private:
        static Singleton* volatile m_ps;
        static mutex m_mutex;
        static GC m_gc;
};

Singleton* volatile Singleton::m_ps = nullptr;
mutex Singleton::m_mutex;
Singleton::GC m_gc;

Singleton* Singleton::GetInstrance()
{
    if (nullptr == m_ps)
    {
        m_mutex.lock();
        if (nullptr == m_ps)
        {    
            m_ps = new Singleton();
            cout << "Create success" << endl;
        }
        m_mutex.unlock();
    }
    return m_ps;
}

Singleton::GC::~GC()
{
    if (nullptr == m_ps)
    {
        if (nullptr == m_ps)
        {    
            delete m_ps;
            m_ps = nullptr;
        }
    }
}

Singleton::Singleton()
{}

void func(int a)
{
    Singleton::GetInstrance();
}

int main()
{
    thread t1(func, 10);
    thread t2(func, 10);
    t1.join();
    t2.join();
    cout << Singleton::GetInstrance() << endl;
    cout << Singleton::GetInstrance() << endl;
    return 0;
}

C++ 11 后的方法

class Singleton
{
public:
	static Singleton* getInstance();
	static std::atomic<Singleton*> Singleton::m_instance;
	static std::mutex Singleton::m_mutex;
private:
	Singleton() = delete;
	Singleton(const Singleton& other) = delete;
};
std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;
Singleton* Singleton::getInstance()
{
	Singleton* temp = m_instance.load(std::memory_order_relaxed);
	std::_Atomic_thread_fence(std::memory_order_acquire);
	if (temp == nullptr)
	{
		std::lock_guard<std::mutex> lock(m_mutex);
		temp = m_instance.load(std::memory_order_relaxed);
		if (temp == nullptr)
		{
			m_instance = new Singleton;
			std::atomic_thread_fence(std::memory_order_release);
			m_instance.store(temp, std::memory_order_relaxed);
		}
	}
	return temp;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值