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博客