C++单例模式

 C++ 单例模式_c++单例模式-CSDN博客

文章内容来自上面的文章

#include <iostream>
#include "widget.h"
using namespace std;

/*
*	版本1 SingletonPattern_V1 存在以下两个问题
*
*	1. 线程不安全, 非线程安全版本
*	2. 内存泄露
*/

class SingletonPattern_V1
{
private:
    SingletonPattern_V1() {
        cout << "constructor called!" << endl;
    }
    SingletonPattern_V1(SingletonPattern_V1&) = delete;
    SingletonPattern_V1& operator=(const SingletonPattern_V1&) = delete;
    static SingletonPattern_V1* m_pInstance;

public:
    ~SingletonPattern_V1() {
        cout << "destructor called!" << endl;
    }
    //在这里实例化
    static SingletonPattern_V1* Instance() {
        if (!m_pInstance) {
            m_pInstance = new SingletonPattern_V1();
        }
        return m_pInstance;
    }
    void use() const { cout << "in use" << endl; }
};
//在类外初始化静态变量
SingletonPattern_V1* SingletonPattern_V1::m_pInstance = nullptr;

//函数入口
int main(int argc, char *argv[])
{
    //测试
    SingletonPattern_V1* p1 = SingletonPattern_V1::Instance();
    SingletonPattern_V1* p2 = SingletonPattern_V1::Instance();
    p1->use();
    p2->use();
    return 0;
}

constructor called!

in use

in use

容易知道此时是内存泄漏的 

线程安全:

多线程中:

static SingletonPattern_V1* Instance() {
		if (!m_pInstance) {
			m_pInstance = new SingletonPattern_V1();
		}
		return m_pInstance;
	}

执行该段代码时,if(!m_pInstance),如果线程A和线程B都判断为空,都开始初始化实例,那么会初始化两次.此时需要加锁.

解决问题后的代码:

#include <iostream>
using namespace std;
#include <memory> // C++11 shared_ptr头文件
#include <mutex>  // C++11 mutex头文件
/*
*	版本2 SingletonPattern_V2 解决了V1中的问题
*
*	1. 通过加锁让线程安全了
*	2. 通过智能指针(shareptr 基于引用计数)内存没有泄露了
*/
class SingletonPattern_V2 
{
public:
	~SingletonPattern_V2() {
		std::cout << "destructor called!" << std::endl;
	}
	SingletonPattern_V2(SingletonPattern_V2&) = delete;
	SingletonPattern_V2& operator=(const SingletonPattern_V2&) = delete;
 
	//在这里实例化
	static std::shared_ptr<SingletonPattern_V2> Instance() 
	{
		//双重检查锁
		if (m_pInstance == nullptr) {
			std::lock_guard<std::mutex> lk(m_mutex);
			if (m_pInstance == nullptr) {
				m_pInstance = std::shared_ptr<SingletonPattern_V2>(new SingletonPattern_V2());
			}
		}
		return m_pInstance;
	}
 
private:
	SingletonPattern_V2() {
		std::cout << "constructor called!" << std::endl;
	}
	static std::shared_ptr<SingletonPattern_V2> m_pInstance;
	static std::mutex m_mutex;
};
 
//在类外初始化静态变量
std::shared_ptr<SingletonPattern_V2> SingletonPattern_V2::m_pInstance = nullptr;
std::mutex SingletonPattern_V2::m_mutex;
 
int main()
{
	std::shared_ptr<SingletonPattern_V2> p1 = SingletonPattern_V2::Instance();
	std::shared_ptr<SingletonPattern_V2> p2 = SingletonPattern_V2::Instance();
 
	system("pause");
	return 0;
}

用智能共享指针和锁把上面的问题给解决了. 

SingletonPattern_V2(SingletonPattern_V2&) = delete;

C++11中=delete的巧妙用法_= delete-CSDN博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lpl还在学习的路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值